Browse Source

Inital Commit

david 4 years ago
commit
af9f5c5839
12 changed files with 748 additions and 0 deletions
  1. 3 0
      .gitignore
  2. 13 0
      CMakeLists.txt
  3. 52 0
      DOOR.SYS
  4. 3 0
      README.md
  5. 21 0
      ansis/sc_mainh.ans
  6. 21 0
      ansis/sc_mainl.ans
  7. 38 0
      cmake/FindSQLite3.cmake
  8. 94 0
      docs/Ship.md
  9. 6 0
      logs/20200629.log
  10. 493 0
      main.c
  11. 4 0
      run.sh
  12. BIN
      spaceconstruct.db3

+ 3 - 0
.gitignore

@@ -0,0 +1,3 @@
+build/
+example-sqlite3/
+MagiDoor/

+ 13 - 0
CMakeLists.txt

@@ -0,0 +1,13 @@
+
+cmake_minimum_required(VERSION 3.0)
+project(testdoors)
+
+set (CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
+find_package(SQLite3 REQUIRED)
+
+add_subdirectory(MagiDoor)
+include_directories(${SQLITE3_INCLUDE_DIRS})
+
+add_executable(main main.c)
+target_link_libraries(main mdoor ${SQLITE3_LIBRARIES})
+

+ 52 - 0
DOOR.SYS

@@ -0,0 +1,52 @@
+COM0:
+38400
+8
+1
+115200
+Y
+N
+Y
+Y
+BEAN ZILLA
+BBS Archives
+805-493-8318
+805-493-8328
+
+99
+2630
+12-28-95
+1440
+499
+GR
+25
+N
+
+
+12-31-99
+43
+
+80
+203
+0
+65535
+01-01-69
+\BBS\MESSAGES\
+\BBS\MESSAGES\
+Mike Ehlert
+Beanzilla
+19:52
+N
+N
+Y
+11
+0
+12-28-98
+15:43
+16:52
+32768
+0
+16252
+43427
+
+0
+867

+ 3 - 0
README.md

@@ -0,0 +1,3 @@
+# Space Construct
+
+A Space Door Game!

+ 21 - 0
ansis/sc_mainh.ans

@@ -0,0 +1,21 @@
+[?7hÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
+ ³ÜßßßÜ ßÛßßÜ  ßÛßßÜ   ÜßßßÜ ÜßÛßßßßþ    ³
+ ³   þ  úÛÛ   Û  Û   Û ÛÛþ³
+ ³ú  ßßÜÜ  ßÛßßß  ßÛßßßÛ Û    ú  ÜÛÜÜú³
+ ³    ú  úÛ  Û  ú   Û   Û Ûß Û³
+ ³ßÜÜÜÜß ßÜß  Üß ßÜÜÜÜß  ÜßÜÜÜÜúú    ³
+ ³³
+ ³ÜßßßÜ  ÜßßßÜ ßÛÜ   ßÜ  ÜßßßÜ ÛßßÜßßÛ ßÛßßÜ  ÜÜ    ßÜ  ÜßßßÜ ÛßßÜßßÛ    ³
+ ³    ÛÛ    Û  Û Û   Û ÛÛÛ   Û  ÛÛ ÛÛ³
+ ³    Û    ú Û    Ûú Û  Û  Û  ßßÜÜ   ú Û    ßÛßÛß   Û ú   Û ÛÛ³
+ ³    ÛÛ    Û  Û   Û ÛÛ    ÛÛ  ßÜ  ÛÛ ÛÛ³
+ ³    ßÜÜÜÜß ßÜÜÜÜß Üß   ßÜß ßÜÜÜÜß   ÜÛÜ   ß    ß ÜßÜÜÜÜÜß ßÜÜÜÜß   ÜÛܳ
+ ³³
+ ³(P)layúúú   ³
+ ³   ú  úþ    (L)ist Players³
+ ³(V)ersionBy: Beanzilla (21:4/110) ³
+ ³(E)dit Game³
+ ³  úú(Q)uitOnú³
+ ³fsxNet³
+ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
+

+ 21 - 0
ansis/sc_mainl.ans

@@ -0,0 +1,21 @@
+[?7hÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
+ ³ÜßßßÜ ßÛßßÜ  ßÛßßÜ   ÜßßßÜ ÜßÛßßßßþ    ³
+ ³   þ  úÛÛ   Û  Û   Û ÛÛþ³
+ ³ú  ßßÜÜ  ßÛßßß  ßÛßßßÛ Û    ú  ÜÛÜÜú³
+ ³    ú  úÛ  Û  ú   Û   Û Ûß Û³
+ ³ßÜÜÜÜß ßÜß  Üß ßÜÜÜÜß  ÜßÜÜÜÜúú    ³
+ ³³
+ ³ÜßßßÜ  ÜßßßÜ ßÛÜ   ßÜ  ÜßßßÜ ÛßßÜßßÛ ßÛßßÜ  ÜÜ    ßÜ  ÜßßßÜ ÛßßÜßßÛ    ³
+ ³    ÛÛ    Û  Û Û   Û ÛÛÛ   Û  ÛÛ ÛÛ³
+ ³    Û    ú Û    Ûú Û  Û  Û  ßßÜÜ   ú Û    ßÛßÛß   Û ú   Û ÛÛ³
+ ³    ÛÛ    Û  Û   Û ÛÛ    ÛÛ  ßÜ  ÛÛ ÛÛ³
+ ³    ßÜÜÜÜß ßÜÜÜÜß Üß   ßÜß ßÜÜÜÜß   ÜÛÜ   ß    ß ÜßÜÜÜÜÜß ßÜÜÜÜß   ÜÛܳ
+ ³³
+ ³(P)layúúú   ³
+ ³   ú  úþ    (L)ist Players³
+ ³(V)ersionBy: Beanzilla (21:4/110) ³
+ ³³
+ ³  úú(Q)uitOnú³
+ ³fsxNet³
+ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
+

+ 38 - 0
cmake/FindSQLite3.cmake

@@ -0,0 +1,38 @@
+# Copyright (C) 2007-2009 LuaDist.
+# Created by Peter Kapec <[email protected]>
+# Redistribution and use of this file is allowed according to the terms of the MIT license.
+# For details see the COPYRIGHT file distributed with LuaDist.
+#	Note:
+#		Searching headers and libraries is very simple and is NOT as powerful as scripts
+#		distributed with CMake, because LuaDist defines directories to search for.
+#		Everyone is encouraged to contact the author with improvements. Maybe this file
+#		becomes part of CMake distribution sometimes.
+
+# - Find sqlite3
+# Find the native SQLITE3 headers and libraries.
+#
+# SQLITE3_INCLUDE_DIRS	- where to find sqlite3.h, etc.
+# SQLITE3_LIBRARIES	- List of libraries when using sqlite.
+# SQLITE3_FOUND	- True if sqlite found.
+
+# Look for the header file.
+FIND_PATH(SQLITE3_INCLUDE_DIR NAMES sqlite3.h)
+
+# Look for the library.
+#FIND_LIBRARY(SQLITE3_LIBRARY NAMES sqlite)
+FIND_LIBRARY(SQLITE3_LIBRARY NAMES sqlite3)
+
+# Handle the QUIETLY and REQUIRED arguments and set SQLITE3_FOUND to TRUE if all listed variables are TRUE.
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SQLITE3 DEFAULT_MSG SQLITE3_LIBRARY SQLITE3_INCLUDE_DIR)
+
+# Copy the results to the output variables.
+IF(SQLITE3_FOUND)
+	SET(SQLITE3_LIBRARIES ${SQLITE3_LIBRARY})
+	SET(SQLITE3_INCLUDE_DIRS ${SQLITE3_INCLUDE_DIR})
+ELSE(SQLITE3_FOUND)
+	SET(SQLITE3_LIBRARIES)
+	SET(SQLITE3_INCLUDE_DIRS)
+ENDIF(SQLITE3_FOUND)
+
+MARK_AS_ADVANCED(SQLITE3_INCLUDE_DIRS SQLITE3_LIBRARIES)

+ 94 - 0
docs/Ship.md

@@ -0,0 +1,94 @@
+# Space Construct
+
+## Ships
+
+A ship contains the player and within a ship a player can build/craft, and as the captain of the ship a player can invite other players to be guests.
+
+### Resources
+
+All items require resources of various types...
+
+```
+Metal (Classified a Common resource)
+Explosive (Classified a Basic resource)
+Crystal (Classified a Rare resource)
+Power (Produced by a Generator and stored by a Battery and consumed by various items)
+Fuel (Consumed per action, without a fuel pod a ship has 20 fuel and gains 6 for each pod)
+Ammo (Consumed by Guns)
+```
+
+### Thrust to Movement speed
+
+A ship contains mass, therefore to go faster a ship can either have less mass or more thrusters installed.
+
+```
+Armor increases mass by 3, (Both Good and Bad Armor increase by 3 mass)
+Shields by 1, (Regardless the Shield level it only increases by 1)
+Solar Panels by 1,
+Guns by 2, (Designed for offense as such has a bit more mass)
+Thrusters provide thrust for 7 which means reduce mass by 7 (a negative mass means 1 mass)
+Shopers by 2, (Since you can buy and sell stuff for credits its a bit big)
+Transporters by 3, (Due to there technology its big, very big)
+Fuel Pods by 2, (Each pod increases total amount of fuel you can have, and thus takes more mass)
+Batteries by 1,
+Generators by 2, (Generates power as such requires more mass)
+```
+
+### Taking Damage
+
+A ship by default comes with 1 Armor (Good), 1 Gun, 1 Thruster, 1 Battery, and 1 Generator (This gives the default ship with +1 mass or about 1 fuel consumed per action)
+
+```
+Armor must be repaired to become useful as such to repair it will require 1 metal.
+Shields will gradually regenerate with energy consumed. (1 for sustaining shields, and 2 while regenerating).
+```
+
+### Calculating Hit Points
+
+For almost everything the hull adjusts to give more space... as such you also get more HP for just being a bigger ship... though it costs.
+
+```
+Armor (Good)     = 2 HP (1 from hull, and 1 from being fully repaired armor)
+Armor (Bad)      = 1 HP (1 from hull, and 0 from being damaged armor)
+Shield (Full)    = 3 HP (1 from hull, and 2 from shields being at full charge)
+Shield (Half)    = 2 HP (1 from hull, and 1 from shields being partially charged)
+Shield (Empty)   = 1 HP (1 from hull, and 0 from being depleted)
+Solar Panel      = 1 HP (1 from hull)
+Gun              = 1 HP (1 from hull)
+Thruster         = 1 HP (1 from hull)
+Advanced Crafter = 0 HP (This is a tech, this it does not increase hull or mass)
+Shoper           = 1 HP (1 from hull)
+Fuel Pod         = -1 HP (yes you loose HP due to explosive fuel)
+```
+
+### Energy Costs
+
+Things like Shields, Guns, Shops, Traders and of course Thrusters require Energy
+
+### Producing and Storing Energy
+
+```
+Solar Panels produce a varied amount of 0 to 2 units of energy,
+Generators produce a constant amount of 4 unit of energy,
+Batteries store a amount of 12 units,
+```
+
+### Energy Consumed
+
+```
+Armors take 0 energy in both Good and Bad states and even while being repaired cost 0,
+Shields take 1 energy to maintain Full or Half states and need 2 energy to recharge to Half or Full,
+Guns require 3 energy to fire,
+Thrusters consume 2 energy to provide thrust,
+Shoper requires 1 energy constantly,
+```
+
+### How do you win or get Experience
+
+There really is no goal except to fly around and build/craft or fight other players or go mining on an asteroid.
+
+You gain experience crafting and of course dealing damage and mining also gives experience.
+
+You gain credits selling stuff or resources using a Shoper and there you can buy stuff only if you can craft it... or you can buy other resources.
+
+The scoreboard will show stuff such as Player Name,  Players Ship Name, Players Experience, Players Credits.

+ 6 - 0
logs/20200629.log

@@ -0,0 +1,6 @@
+19:35:59 --- Debug ---
+19:36:39 --- Debug ---
+19:38:30 --- Debug ---
+19:38:55 --- Debug ---
+19:39:03 --- Debug ---
+19:45:11 --- Debug ---

+ 493 - 0
main.c

@@ -0,0 +1,493 @@
+/*
+    Space Construct by Beanzilla
+
+    Beanzilla@21:4/110 on fsxNet
+*/
+
+// Verion 0.1-dev
+#define VERSION_MAJOR 0
+#define VERSION_MINOR 1
+#ifndef VERSION_TYPE
+#define VERSION_TYPE "dev"
+#endif
+
+#define PATH_MAX 256
+#define PATH_SEP "/"
+
+#include <MagiDoor.h>
+#include <sqlite3.h>
+#if defined(_MSC_VER) || defined(WIN32)
+#define snprintf _snprintf
+#define strcasecmp _stricmp
+#include <winsock2.h>
+#ifndef _MSC_VER
+#define _MSC_VER 1
+#endif
+#else
+#include <arpa/inet.h>
+#endif
+
+// Standard C
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h> // stat
+
+char * log_path = "logs";
+int inuse = 0; // Are any other copies of us running? (We are a single door!)
+int debug = 0; // Are we in debug mode?
+
+// User Structure (This includes guns, fuel, armor, shields, HP)
+typedef struct user_info {
+  int uid; // Primary Key
+  int experience; // Think about this as score
+  // Was ship structure, now is part of user
+  int guns; // Placed Guns, More means more damage (Deals from 1-2 damage per attack)
+  int fuel; // How many "turns" do we have
+  int metal; // Used to build more guns/armors/shields possibly fuel too (guns take 5, armor takes 3, shields take 7, maybe fuel takes 12)
+  int armors; // Placed Armors (Each Armor takes 4 points of damage then breaks off)
+  int shields; // Placed Shields (Each Shields takes 3 points of damage then is offline, regenerates 1 point per attack/turn must reach 50% of max to being protecting again)
+  int hitpoints; // Total hitpoints till we die (Rules for taking damage, shields first then armor then hitpoints)
+  int armorpoints; // Points we get from armors (Repairable but costs 1 metal per point, but can break if taking too much damage)
+  int shieldpoints; // Points we get from shields (Self-Regenerates, and does not get destroyed)
+  char nick[256]; // What they go by on score board, this allows duping since we really go by real
+  char real[256]; // Their real name to match with drop file info, prevents someone from loging in as another
+} user_inf;
+
+void dolog(char *fmt, ...) {
+  // Low end Logging
+  char buffer[PATH_MAX];
+  struct tm *time_now;
+  time_t timen;
+  FILE *logfptr;
+
+  timen = time(NULL);
+
+  time_now = localtime(&timen);
+  if (log_path != NULL) {
+    snprintf(buffer, PATH_MAX, "%s%s%04d%02d%02d.log", log_path, PATH_SEP,
+             time_now->tm_year + 1900, time_now->tm_mon + 1, time_now->tm_mday);
+  } else {
+    snprintf(buffer, PATH_MAX, "%04d%02d%02d.log", time_now->tm_year + 1900,
+             time_now->tm_mon + 1, time_now->tm_mday);
+  }
+  logfptr = fopen(buffer, "a");
+  if (!logfptr) {
+    return;
+  }
+  va_list ap;
+  va_start(ap, fmt);
+  vsnprintf(buffer, 512, fmt, ap);
+  va_end(ap);
+
+  fprintf(logfptr, "%02d:%02d:%02d %s\n", time_now->tm_hour, time_now->tm_min,
+          time_now->tm_sec, buffer);
+
+  fclose(logfptr);
+}
+
+void db_test() {
+  sqlite3 *db;
+  sqlite3_stmt *stmt;
+  char sqlbuffer[256];
+  char strbuffer[256];
+  int rc = sqlite3_open("spaceconstruct.db3", &db);
+  if(rc) { // Did we do a successful open?
+    dolog("E: failed opening database %s", sqlite3_errmsg(db));
+    sqlite3_close(db);
+    md_exit(1);
+  }
+  sqlite3_busy_timeout(db, 5000);
+  // DB open
+  strcpy(sqlbuffer, "SELECT * FROM user;");
+  sqlite3_prepare_v2(db, sqlbuffer, strlen(sqlbuffer), &stmt, NULL);
+  while(sqlite3_step(stmt) == SQLITE_ROW) {
+    /* Disabled to reduce logs to errors/warnings
+    dolog("%s=%d %s=%s %s=%s %s=%d %s=%d %s=%d %s=%d %s=%d %s=%d %s=%d %s=%d %s=%d",
+      sqlite3_column_name(stmt, 0), // int,  uid
+      sqlite3_column_int(stmt, 0),
+      sqlite3_column_name(stmt, 1), // text, nick
+      sqlite3_column_text(stmt, 1),
+      sqlite3_column_name(stmt, 2), // text, real
+      sqlite3_column_text(stmt, 2),
+      sqlite3_column_name(stmt, 3), // int,  experiece
+      sqlite3_column_int(stmt, 3),
+      sqlite3_column_name(stmt, 4), // int,  metal
+      sqlite3_column_int(stmt, 4),
+      sqlite3_column_name(stmt, 5), // int,  fuel
+      sqlite3_column_int(stmt, 5),
+      sqlite3_column_name(stmt, 6), // int,  guns
+      sqlite3_column_int(stmt, 6),
+      sqlite3_column_name(stmt, 7), // int,  armors
+      sqlite3_column_int(stmt, 7),
+      sqlite3_column_name(stmt, 8), // int,  shields
+      sqlite3_column_int(stmt, 8),
+      sqlite3_column_name(stmt, 9), // int,  armorpoints
+      sqlite3_column_int(stmt, 9),
+      sqlite3_column_name(stmt, 10), // int, shieldpoints
+      sqlite3_column_int(stmt, 10),
+      sqlite3_column_name(stmt, 11), // int,  hitpoints
+      sqlite3_column_int(stmt, 11)
+    ); */
+    md_printf("`white`%s=%d %s=%s %s=%s %s=%d %s=%d %s=%d %s=%d %s=%d %s=%d %s=%d %s=%d %s=%d\r\n",
+      sqlite3_column_name(stmt, 0), // int,  uid
+      sqlite3_column_int(stmt, 0),
+      sqlite3_column_name(stmt, 1), // text, nick
+      sqlite3_column_text(stmt, 1),
+      sqlite3_column_name(stmt, 2), // text, real
+      sqlite3_column_text(stmt, 2),
+      sqlite3_column_name(stmt, 3), // int,  experiece
+      sqlite3_column_int(stmt, 3),
+      sqlite3_column_name(stmt, 4), // int,  metal
+      sqlite3_column_int(stmt, 4),
+      sqlite3_column_name(stmt, 5), // int,  fuel
+      sqlite3_column_int(stmt, 5),
+      sqlite3_column_name(stmt, 6), // int,  guns
+      sqlite3_column_int(stmt, 6),
+      sqlite3_column_name(stmt, 7), // int,  armors
+      sqlite3_column_int(stmt, 7),
+      sqlite3_column_name(stmt, 8), // int,  shields
+      sqlite3_column_int(stmt, 8),
+      sqlite3_column_name(stmt, 9), // int,  armorpoints
+      sqlite3_column_int(stmt, 9),
+      sqlite3_column_name(stmt, 10), // int, shieldpoints
+      sqlite3_column_int(stmt, 10),
+      sqlite3_column_name(stmt, 11), // int,  hitpoints
+      sqlite3_column_int(stmt, 11)
+    );
+  } // Clean up database
+  sqlite3_finalize(stmt);
+  sqlite3_close(db);
+}
+
+int check_lock() {
+  // Checks stats of lock, (1 = Lock is in effect, 0 = No Lock established)
+  struct stat s;
+  if (stat("lock.flg", &s) == 0) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+void grab_lock() {
+  // Attempt to grab lock
+  int valid = check_lock();
+  FILE *fhandle;
+  if (valid == 0) {
+    fhandle = fopen("lock.flg", "w");
+    if(!fhandle) {
+      dolog("E: Unable to make lock.flg!");
+      fprintf(stderr, "Unable to establish lock!\r\n");
+      md_exit(-1);
+    }
+    fprintf(fhandle, "I am in use already!\n");
+    fclose(fhandle);
+  } else {
+    dolog("W: Lock already established!");
+  }
+}
+
+void rel_lock() {
+  // Attempt to release lock
+  int valid = check_lock();
+  if (valid == 1) {
+    if (unlink("lock.flg") != 0) {
+      dolog("E: Unable to release lock.flg!");
+      fprintf(stderr, "Unable to release lock!\r\n");
+      md_exit(-1);
+    }
+  } else {
+    dolog("W: Lock already released!");
+  }
+}
+
+void log_drop() {
+  // Spits out info from Drop File:
+  /* Disabled to reduce logs to errors/warnings
+  dolog("First=%s Last=%s Alias=%s TimeLeft=%d SecLevel=%d Location=%s Node=%d Socket=%d Sysop=%s",
+    mdcontrol.user_firstname,
+    mdcontrol.user_lastname,
+    mdcontrol.user_alias,
+    mdcontrol.user_timeleft,
+    mdcontrol.user_seclevel,
+    mdcontrol.user_location,
+    mdcontrol.node,
+    mdcontrol.socket,
+    mdcontrol.sysop_name
+  );
+  */
+  md_printf("`white`First=%s Last=%s Alias=%s TimeLeft=%d SecLevel=%d Location=%s Node=%d Socket=%d Sysop=%s\r\n",
+    mdcontrol.user_firstname,
+    mdcontrol.user_lastname,
+    mdcontrol.user_alias,
+    mdcontrol.user_timeleft,
+    mdcontrol.user_seclevel,
+    mdcontrol.user_location,
+    mdcontrol.node,
+    mdcontrol.socket,
+    mdcontrol.sysop_name
+  );
+}
+
+void paws() {
+  // Aaah, DRY
+  md_printf("`white`Press any key to continue...");
+  md_getc();
+  md_printf("\r\n");
+}
+
+int locate_player(char first[], char last[]) {
+  // returns user id for given real name and 0 for no record found
+  sqlite3 *db;
+  sqlite3_stmt *stmt;
+  char sqlbuffer[256];
+  int result = 0;
+  char name[256];
+  int rc = sqlite3_open("spaceconstruct.db3", &db);
+  if(rc) { // Did we do a successful open?
+    dolog("E: failed opening database %s", sqlite3_errmsg(db));
+    sqlite3_close(db);
+    md_exit(1);
+  }
+  sqlite3_busy_timeout(db, 5000);
+  // Form Real Name
+  strcpy(name, "");
+  strcat(name, first);
+  strcat(name, " ");
+  strcat(name, last);
+  //md_printf("realname = '%s'\r\n", name);
+
+  // Locating user with given name
+  strcpy(sqlbuffer, "SELECT * from user where real=? COLLATE NOCASE;");
+  sqlite3_prepare_v2(db, sqlbuffer, strlen(sqlbuffer) + 1, &stmt, NULL);
+  sqlite3_bind_text(stmt, 1, name, strlen(name), SQLITE_STATIC);
+  rc = sqlite3_step(stmt);
+  if (rc == SQLITE_ROW) {
+    //dolog("User=%s uid=%d", name, sqlite3_column_int(stmt, 0));
+    result = sqlite3_column_int(stmt, 0);
+  } else {
+    dolog("W: Unable to locate user=%s", name);
+    result = 0;
+  } // Clean Up, return results
+  sqlite3_finalize(stmt);
+  sqlite3_close(db);
+  return result;
+}
+
+user_inf load_player(int uuid) {
+  // Returns a player Structure from database
+  sqlite3 *db;
+  sqlite3_stmt *stmt;
+  char sqlbuffer[256];
+  user_inf result;
+  int rc = sqlite3_open("spaceconstruct.db3", &db);
+  if(rc) { // Did we do a successful open?
+    dolog("E: failed opening database %s", sqlite3_errmsg(db));
+    sqlite3_close(db);
+    md_exit(1);
+  }
+  sqlite3_busy_timeout(db, 5000);
+  strcpy(sqlbuffer, "SELECT * from user where uid=?;");
+  sqlite3_prepare_v2(db, sqlbuffer, strlen(sqlbuffer) + 1, &stmt, NULL);
+  sqlite3_bind_int(stmt, uuid, 1);
+  rc = sqlite3_step(stmt);
+  if (rc == SQLITE_ROW) {
+    result.uid = sqlite3_column_int(stmt, 0);
+    strcpy(result.nick, sqlite3_column_text(stmt, 1));
+    strcpy(result.real, sqlite3_column_text(stmt, 2));
+    result.experience = sqlite3_column_int(stmt, 3);
+    result.metal = sqlite3_column_int(stmt, 4);
+    result.fuel = sqlite3_column_int(stmt, 5);
+    result.guns = sqlite3_column_int(stmt, 6);
+    result.armors = sqlite3_column_int(stmt, 7);
+    result.shields = sqlite3_column_int(stmt, 8);
+    result.armorpoints = sqlite3_column_int(stmt, 9);
+    result.shieldpoints = sqlite3_column_int(stmt, 10);
+    result.hitpoints = sqlite3_column_int(stmt, 11);
+  } else {
+    dolog("E: Unable to locate user with id=%d", uuid);
+    sqlite3_finalize(stmt);
+    sqlite3_close(db);
+    md_exit(-1);
+  }
+  sqlite3_finalize(stmt);
+  sqlite3_close(db);
+  return result;
+}
+
+void update_player(user_inf data) {
+  sqlite3 *db;
+  sqlite3_stmt *stmt;
+  char sqlbuffer[1024];
+  int rc = sqlite3_open("spaceconstruct.db3", &db);
+  if(rc) { // Did we do a successful open?
+    dolog("E: failed opening database %s", sqlite3_errmsg(db));
+    sqlite3_close(db);
+    md_exit(1);
+  }
+  sqlite3_busy_timeout(db, 5000);
+  // Bad, don't do this... opens to SQL injection!
+  //snprintf(sqlbuffer, 1024, "UPDATE user SET nick = '%s', experience = %d, metal = %d, fuel = %d, guns = %d, armors = %d, shields = %d, armorpoints = %d, shieldpoints = %d, hitpoints = %d WHERE uid=%d;",
+  //  data.nick, data.experience, data.metal, data.fuel, data.guns, data.armors, data.shields, data.armorpoints, data.shieldpoints, data.hitpoints, data.uid);
+  strcpy(sqlbuffer, "UPDATE user SET nick=?, experience=?, metal=?, fuel=?, guns=?, armors=?, shields=?, armorpoints=?, shieldpoints=?, hitpoints=? WHERE uid=?;");
+  sqlite3_prepare_v2(db, sqlbuffer, strlen(sqlbuffer) + 1, &stmt, NULL);
+  // Bind All data values
+  sqlite3_bind_text(stmt, 1, data.nick, strlen(data.nick), SQLITE_STATIC);
+  sqlite3_bind_int(stmt, 2, data.experience);
+  sqlite3_bind_int(stmt, 3, data.metal);
+  sqlite3_bind_int(stmt, 4, data.fuel);
+  sqlite3_bind_int(stmt, 5, data.guns);
+  sqlite3_bind_int(stmt, 6, data.armors);
+  sqlite3_bind_int(stmt, 7, data.shields);
+  sqlite3_bind_int(stmt, 8, data.armorpoints);
+  sqlite3_bind_int(stmt, 9, data.shieldpoints);
+  sqlite3_bind_int(stmt, 10, data.hitpoints);
+  sqlite3_bind_int(stmt, 11, data.uid);
+  // Execute
+  rc = sqlite3_step(stmt);
+  if(rc != SQLITE_DONE) {
+    dolog("E: failed updating player=%d got error %s (%d)", data.uid, sqlite3_errmsg(db), rc);
+    sqlite3_finalize(stmt);
+    sqlite3_close(db);
+    md_exit(-1);
+  }
+  sqlite3_finalize(stmt);
+  sqlite3_close(db);
+}
+
+void main_menu() {
+  // Main menu for once things are done being initalized
+  int done = 0;
+  char ch;
+  while(!done) {
+    md_clr_scr();
+    if(mdcontrol.user_seclevel == 99 || mdcontrol.user_seclevel == 255) { // Display a menu for sysops
+      md_sendfile("ansis/sc_mainh.ans", TRUE);
+      ch = md_get_answer("PpLlVvQqEe\r");
+    } else { // And display a different menu for non-sysops
+      md_sendfile("ansis/sc_mainl.ans", TRUE);
+      ch = md_get_answer("PpLlVvQq\r");
+    }
+    md_clr_scr();
+    switch(tolower(ch)){
+      case 'q':
+        // Quit
+        md_printf("`bright white`Farewell!\r\n");
+        // Hmm sleep?
+        done = 1;
+        break;
+      case '\r':
+      case 'p':
+        // Play Game (Default if the player just hits enter)
+        if (inuse == 1) {
+          md_printf("`bright red`Game in use!\r\n");
+        } else {
+          md_printf("`bright white`Play\r\n");
+        }
+        paws();
+        break;
+      case 'l':
+        // List Players in the game
+        md_printf("`bright red`There are no players!\r\n");
+        paws();
+        break;
+      case 'v':
+        // Version
+        md_clr_scr();
+        md_printf("`bright yellow`|--------------------------|\r\n");
+        md_printf("`bright yellow`| Space Construct v%d.%d-%s |\r\n", VERSION_MAJOR, VERSION_MINOR, VERSION_TYPE);
+        md_printf("`bright yellow`|--------------------------|\r\n");
+        paws();
+        break;
+      case 'e':
+        // Edit Game (User Editor, Game Settings)
+        if(mdcontrol.user_seclevel == 99 || mdcontrol.user_seclevel == 255) {
+          md_printf("`bright green`Sysop Menu\r\n");
+          paws();
+          break;
+        }
+    }
+  }
+}
+
+int main(int argc, char **argv) {
+  int socket;
+  if (argc < 2) { // Not enough arguments
+    fprintf(stderr, "usage:\n%s (DROPFILE [SOCKET])\r\n", argv[0]);
+    dolog("E %s (DROPFILE [SOCKET])", argv[0]);
+    return 0;
+  }
+  if (argc > 2) { // If socket is found use socket
+    if (argv[2][0] >= '0' && argv[2][0] <= '9') {
+      socket = strtol(argv[2], NULL, 10);
+    } else {
+      socket = -1;
+    }
+  } else {
+    socket = -1;
+  }
+  // Initiate MagiDoor
+  md_init(argv[1], socket);
+  md_clr_scr();
+
+  // Debug System
+  if (debug) {
+    dolog("=== Debug ===");
+    md_printf("`white`=== Debug ===\r\n");
+    md_printf("DropFile...\r\n");
+    log_drop();
+    int test = check_lock();
+    if (test == 0) {
+      md_printf("Lock is: Avalible\r\n");
+      md_printf("Database...\r\n");
+      db_test();
+    } else {
+      md_printf("Lock is: Taken\r\n");
+      md_printf("CANCELED Database Dump\r\n");
+    }
+    md_printf("`bright green`Continue to Program?\r\n");
+    md_printf("`bright black`(`bright white`Y`bright black`)`white`es `bright black`(`bright red`N`bright black`)`red`o");
+    char t = md_get_answer("YyNn\r");
+    md_printf("\r\n`white`");
+    switch(tolower(t)) {
+      case '\r':
+      case 'y':
+        break;
+      case 'n':
+        md_exit(0);
+        break;
+    }
+    md_clr_scr();
+  } else {
+    dolog("--- Debug ---");
+  }
+
+  // Check Lock
+  inuse = check_lock();
+  // 0 means we got the lock first, 1 means someone else has it already!
+
+  // Lock game
+  if (inuse == 0) {
+    grab_lock();
+  }
+
+  // Main Menu
+  //main_menu();
+  user_inf ply = load_player(locate_player(mdcontrol.user_firstname, mdcontrol.user_lastname));
+  ply.experience += 10;
+  update_player(ply);
+
+  // Unlock game
+  if (inuse == 0) {
+    rel_lock();
+  }
+
+  // Goodbye
+  md_exit(0);
+}

+ 4 - 0
run.sh

@@ -0,0 +1,4 @@
+#!/bin/bash
+
+cd ~/SpaceConstruct/
+./build/main DOOR.SYS

BIN
spaceconstruct.db3