Add gametime support, and other stuff

This commit is contained in:
SilicaAndPina 2020-09-30 01:46:27 +13:00
parent e8e0a0a519
commit c1c3a9ee82
162 changed files with 95566 additions and 596 deletions

View file

@ -57,26 +57,23 @@ namespace Horse_Isle_Server
{
byte[] plaintextBytes = Encoding.UTF8.GetBytes(plaintext);
SHA512 sha512 = SHA512.Create();
sha512.Initialize();
byte[] hash = sha512.TransformFinalBlock(plaintextBytes, 0x00, plaintextBytes.Length);
SHA512 sha512 = new SHA512Managed();
byte[] hash = sha512.ComputeHash(plaintextBytes);
for (int i = 0; i < hash.Length; i++)
{
hash[i] ^= salt[i];
}
sha512 = SHA512.Create();
sha512.Initialize();
byte[] finalHash = sha512.TransformFinalBlock(hash, 0x00, hash.Length);
byte[] finalHash = sha512.ComputeHash(hash);
return finalHash;
}
public static bool CheckPassword(string username, string password)
{
try
if(Database.CheckUserExist(username))
{
byte[] expectedPassword = Database.GetPasswordHash(username);
byte[] salt = Database.GetPasswordSalt(username);
@ -84,14 +81,8 @@ namespace Horse_Isle_Server
if (Enumerable.SequenceEqual(expectedPassword, hashedPassword))
return true;
else
return false;
}
catch(KeyNotFoundException e)
{
Logger.DebugPrint(e.Message);
return false;
}
return false;
}
}

View file

@ -14,7 +14,9 @@ namespace Horse_Isle_Server
{
public Socket ClientSocket;
public string RemoteIp;
public bool LoggedIn = false;
public User LoggedinUser;
private Thread recvPackets;
@ -23,6 +25,11 @@ namespace Horse_Isle_Server
private const byte PACKET_MOVE = 0x15;
private const byte PACKET_USERINFO = 0x81;
public void Login(int id)
{
LoggedinUser = new User(id);
LoggedIn = true;
}
private void receivePackets()
{
// HI1 Packets are terminates by 0x00 so we have to read until we receive that terminator

View file

@ -15,10 +15,11 @@ namespace Horse_Isle_Server
public static string DatabaseName;
public static string DatabasePassword;
public static int DatabasePort;
public static string Motd;
public static string MapFile;
public static string OverlayMapFile;
public static string GameDataFile;
public static string CrossDomainPolicyFile;
public static bool Debug;
@ -78,6 +79,12 @@ namespace Horse_Isle_Server
case "map":
MapFile = data;
break;
case "motd":
Motd = data;
break;
case "gamedata":
GameDataFile = data;
break;
case "overlaymap":
OverlayMapFile = data;
break;

View file

@ -14,7 +14,7 @@ namespace Horse_Isle_Server
{
if (!File.Exists(ConfigReader.CrossDomainPolicyFile)) {
if (ConfigReader.Debug)
Console.WriteLine("[DEBUG] Cross domain policy file not found, using default");
Console.WriteLine("[DEBUG] Cross-Domain-Policy file not found, using default");
File.WriteAllText(ConfigReader.CrossDomainPolicyFile, Resources.DefaultCrossDomain);
}

View file

@ -14,6 +14,8 @@ namespace Horse_Isle_Server
db = new MySqlConnection("server=" + ConfigReader.DatabaseIP + ";user=" + ConfigReader.DatabaseUsername + ";password=" + ConfigReader.DatabasePassword+";database="+ConfigReader.DatabaseName);
db.Open();
string UserTable = "CREATE TABLE Users(Id INT, Username TEXT(16),Email TEXT(128),Country TEXT(128),SecurityQuestion Text(128),SecurityAnswerHash TEXT(128),Age INT,PassHash TEXT(128), Salt TEXT(128),Gender TEXT(16), Admin TEXT(3), Moderator TEXT(3))";
string ExtTable = "CREATE TABLE UserExt(Id INT, X INT, Y INT, Money INT, BankBalance BIGINT,ProfilePage Text(1028), CharId, INT)";
string WorldTable = "CREATE TABLE World(TimeStarted INT, Weather TEXT(64)";
try
{
@ -23,19 +25,78 @@ namespace Horse_Isle_Server
sqlCommand.ExecuteNonQuery();
}
catch (Exception e) {
Logger.ErrorPrint("Failed to setup database (perhaps its allready setup?) "+e.Message);
Logger.WarnPrint(e.Message);
};
try
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = ExtTable;
sqlCommand.ExecuteNonQuery();
}
catch (Exception e)
{
Logger.WarnPrint(e.Message);
};
try
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = WorldTable;
sqlCommand.ExecuteNonQuery();
int epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "INSERT INTO World VALUES(@unix,'SUNNY')";
sqlCommand.Parameters.AddWithValue("@unix", epoch);
sqlCommand.Prepare();
sqlCommand.ExecuteNonQuery();
}
catch (Exception e)
{
Logger.WarnPrint(e.Message);
};
}
public static int GetServerCreationTime()
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT TimeStarted FROM World";
int creationTime = Convert.ToInt32(sqlCommand.ExecuteScalar());
return creationTime;
}
public static string GetWorldWeather()
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT Weather FROM World";
string Weather = sqlCommand.ExecuteScalar().ToString();
return Weather;
}
public static void SetWorldWeather(string Weather)
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "UPDATE World SET Weather=@weather";
sqlCommand.Parameters.AddWithValue("@weather", Weather);
sqlCommand.Prepare();
sqlCommand.ExecuteNonQuery();
}
public static byte[] GetPasswordSalt(string username)
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT COUNT(1) FROM Users WHERE Username=$name";
sqlCommand.Parameters.AddWithValue("$name", username);
Int32 count = Convert.ToInt32(sqlCommand.ExecuteScalar());
if (count >= 1)
if (CheckUserExist(username))
{
sqlCommand.CommandText = "SELECT Salt FROM Users WHERE Username=$name";
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT Salt FROM Users WHERE Username=@name";
sqlCommand.Parameters.AddWithValue("@name", username);
sqlCommand.Prepare();
string expectedHash = sqlCommand.ExecuteScalar().ToString();
return Converters.StringToByteArray(expectedHash);
}
@ -44,15 +105,332 @@ namespace Horse_Isle_Server
throw new KeyNotFoundException("Username " + username + " not found in database.");
}
}
public static byte[] GetPasswordHash(string username)
public static bool CheckUserExist(int id)
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT COUNT(1) FROM Users WHERE Username=$name";
sqlCommand.Parameters.AddWithValue("$name", username);
sqlCommand.CommandText = "SELECT COUNT(1) FROM Users WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@id", id);
sqlCommand.Prepare();
Int32 count = Convert.ToInt32(sqlCommand.ExecuteScalar());
if(count >= 1)
return count >= 1;
}
public static bool CheckUserExist(string username)
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT COUNT(1) FROM Users WHERE Username=@name";
sqlCommand.Parameters.AddWithValue("@name", username);
sqlCommand.Prepare();
Int32 count = Convert.ToInt32(sqlCommand.ExecuteScalar());
return count >= 1;
}
public static bool CheckUserExtExists(int id)
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT COUNT(1) FROM UserExt WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@id", id);
sqlCommand.Prepare();
Int32 count = Convert.ToInt32(sqlCommand.ExecuteScalar());
return count >= 1;
}
public static bool CheckUserIsModerator(string username)
{
if (CheckUserExist(username))
{
sqlCommand.CommandText = "SELECT PassHash FROM Users WHERE Username=$name";
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT Moderator FROM Users WHERE Username=@name";
sqlCommand.Parameters.AddWithValue("@name", username);
sqlCommand.Prepare();
string modStr = sqlCommand.ExecuteScalar().ToString();
return modStr == "YES";
}
else
{
throw new KeyNotFoundException("Username " + username + " not found in database.");
}
}
public static bool CheckUserIsAdmin(string username)
{
if (CheckUserExist(username))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT Admin FROM Users WHERE Username=@name";
sqlCommand.Parameters.AddWithValue("@name", username);
sqlCommand.Prepare();
string adminStr = sqlCommand.ExecuteScalar().ToString();
return adminStr == "YES";
}
else
{
throw new KeyNotFoundException("Username " + username + " not found in database.");
}
}
public static void CreateUserExt(int id)
{
if (CheckUserExtExists(id)) // user allready exists!
throw new Exception("Userid " + id + " Allready in userext.");
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "INSERT INTO UserExt VALUES(@id,@x,@y,0,0,'',5)";
sqlCommand.Parameters.AddWithValue("@id", id);
sqlCommand.Parameters.AddWithValue("@x", Gamedata.NewUserStartX);
sqlCommand.Parameters.AddWithValue("@y", Gamedata.NewUserStartY);
sqlCommand.Prepare();
sqlCommand.ExecuteNonQuery();
}
public static int GetUserid(string username)
{
if (CheckUserExist(username))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT Id FROM Users WHERE Username=@name";
sqlCommand.Parameters.AddWithValue("@name", username);
sqlCommand.Prepare();
int userId = Convert.ToInt32(sqlCommand.ExecuteScalar());
return userId;
}
else
{
throw new KeyNotFoundException("Username " + username + " not found in database.");
}
}
public static int GetPlayerCharId(int userId)
{
if (CheckUserExtExists(userId))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT CharId FROM UserExt WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@id", userId);
sqlCommand.Prepare();
int CharId = Convert.ToInt32(sqlCommand.ExecuteScalar());
return CharId;
}
else
{
throw new KeyNotFoundException("Id " + userId + " not found in database.");
}
}
public static void SetPlayerCharId(int charid, int id)
{
if (CheckUserExist(id))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "UPDATE UserExt SET CharId=@charId WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@charId", charid);
sqlCommand.Parameters.AddWithValue("@id", id);
sqlCommand.Prepare();
sqlCommand.ExecuteNonQuery();
}
else
{
throw new KeyNotFoundException("Id " + id + " not found in database.");
}
}
public static int GetPlayerX(int userId)
{
if (CheckUserExtExists(userId))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT X FROM UserExt WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@id", userId);
sqlCommand.Prepare();
int X = Convert.ToInt32(sqlCommand.ExecuteScalar());
return X;
}
else
{
throw new KeyNotFoundException("Id " + userId + " not found in database.");
}
}
public static void SetPlayerX(int x, int id)
{
if (CheckUserExist(id))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "UPDATE UserExt SET X=@x WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@x", x);
sqlCommand.Parameters.AddWithValue("@id", id);
sqlCommand.Prepare();
sqlCommand.ExecuteNonQuery();
}
else
{
throw new KeyNotFoundException("Id " + id + " not found in database.");
}
}
public static int GetPlayerY(int userId)
{
if (CheckUserExtExists(userId))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT Y FROM UserExt WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@id", userId);
sqlCommand.Prepare();
int Y = Convert.ToInt32(sqlCommand.ExecuteScalar());
return Y;
}
else
{
throw new KeyNotFoundException("Id " + userId + " not found in database.");
}
}
public static void SetPlayerY(int y, int id)
{
if (CheckUserExist(id))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "UPDATE UserExt SET Y=@y WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@y", y);
sqlCommand.Parameters.AddWithValue("@id", id);
sqlCommand.Prepare();
sqlCommand.ExecuteNonQuery();
}
else
{
throw new KeyNotFoundException("Id " + id + " not found in database.");
}
}
public static void SetPlayerMoney(int money, int id)
{
if (CheckUserExist(id))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "UPDATE UserExt SET Money=@money WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@money", money);
sqlCommand.Parameters.AddWithValue("@id", id);
sqlCommand.Prepare();
sqlCommand.ExecuteNonQuery();
}
else
{
throw new KeyNotFoundException("Id " + id + " not found in database.");
}
}
public static int GetPlayerMoney(int userId)
{
if (CheckUserExtExists(userId))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT Money FROM UserExt WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@id", userId);
sqlCommand.Prepare();
int Money = Convert.ToInt32(sqlCommand.ExecuteScalar());
return Money;
}
else
{
throw new KeyNotFoundException("Id " + userId + " not found in database.");
}
}
public static int GetPlayerBankMoney(int userId)
{
if (CheckUserExtExists(userId))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT BankBalance FROM UserExt WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@id", userId);
sqlCommand.Prepare();
int BankMoney = Convert.ToInt32(sqlCommand.ExecuteScalar());
return BankMoney;
}
else
{
throw new KeyNotFoundException("Id " + userId + " not found in database.");
}
}
public static void SetPlayerBankMoney(int bankMoney, int id)
{
if (CheckUserExist(id))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "UPDATE UserExt SET BankBalance=@bankMoney WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@bankMoney", bankMoney);
sqlCommand.Parameters.AddWithValue("@id", id);
sqlCommand.Prepare();
sqlCommand.ExecuteNonQuery();
}
else
{
throw new KeyNotFoundException("Id " + id + " not found in database.");
}
}
public static void SetPlayerProfile(string profilePage, int id)
{
if (CheckUserExist(id))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "UPDATE UserExt SET ProfilePage=@profilePage WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@profilePage", profilePage);
sqlCommand.Parameters.AddWithValue("@id", id);
sqlCommand.Prepare();
sqlCommand.ExecuteNonQuery();
}
else
{
throw new KeyNotFoundException("Id " + id + " not found in database.");
}
}
public static string GetPlayerProfile(int id)
{
if (CheckUserExist(id))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT ProfilePage FROM UserExt WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@id", id);
sqlCommand.Prepare();
string profilePage = sqlCommand.ExecuteScalar().ToString();
return profilePage;
}
else
{
throw new KeyNotFoundException("Id " + id + " not found in database.");
}
}
public static string GetUsername(int userId)
{
if(CheckUserExist(userId))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT Username FROM Users WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@id", userId);
sqlCommand.Prepare();
string username = sqlCommand.ExecuteScalar().ToString();
return username;
}
else
{
throw new KeyNotFoundException("Id " + userId + " not found in database.");
}
}
public static byte[] GetPasswordHash(string username)
{
if(CheckUserExist(username))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT PassHash FROM Users WHERE Username=@name";
sqlCommand.Parameters.AddWithValue("@name", username);
sqlCommand.Prepare();
string expectedHash = sqlCommand.ExecuteScalar().ToString();
return Converters.StringToByteArray(expectedHash);
}

View file

@ -0,0 +1,71 @@
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
namespace Horse_Isle_Server
{
internal class Isle
{
public int StartX = 0;
public int EndX = 0;
public int StartY = 0;
public int EndY = 0;
public int Tileset = 0;
public string Name;
public Isle(int startx, int starty, int endx, int endy, int tileset, string name)
{
StartX = startx;
StartY = starty;
EndX = endx;
EndY = endy;
Tileset = tileset;
Name = name;
}
}
class Gamedata
{
public static List<Isle> Isles = new List<Isle>();
public static int NewUserStartX;
public static int NewUserStartY;
public static string NewUserMessage;
public static void ReadGamedata()
{
if(!File.Exists(ConfigReader.GameDataFile))
{
Logger.ErrorPrint("Game Data JSON File: " + ConfigReader.GameDataFile + " Does not exist!");
return;
}
string jsonData = File.ReadAllText(ConfigReader.GameDataFile);
dynamic gameData = JsonConvert.DeserializeObject(jsonData);
int totalIsles = gameData.isles.Count;
for(int i = 0; i < totalIsles; i++)
{
int startx = gameData.isles[i].start_x;
int starty = gameData.isles[i].start_y;
int endx = gameData.isles[i].end_x;
int endy = gameData.isles[i].end_y;
int tileset = gameData.isles[i].tileset;
string name = gameData.isles[i].name;
Logger.DebugPrint("Registered Isle: " + name + " X " + startx + "-" + endx + " Y " + starty + "-" + endy + " tileset: " + tileset);
Isles.Add(new Isle(startx, starty, endx, endy, tileset, name));
}
NewUserMessage = gameData.new_user.starting_message;
Logger.DebugPrint("New User Message: " + NewUserMessage);
NewUserStartX = gameData.new_user.starting_x;
Logger.DebugPrint("New User Start X: " + NewUserStartX);
NewUserStartY = gameData.new_user.starting_y;
Logger.DebugPrint("New User Start Y: " + NewUserStartY);
}
}
}

View file

@ -42,6 +42,9 @@
<Reference Include="MySqlConnector, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d33d3e53aa5f8c92, processorArchitecture=MSIL">
<HintPath>..\packages\MySqlConnector.1.0.1\lib\net471\MySqlConnector.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
@ -70,9 +73,11 @@
<Compile Include="Client.cs" />
<Compile Include="Converters.cs" />
<Compile Include="Database.cs" />
<Compile Include="Gamedata.cs" />
<Compile Include="Logger.cs" />
<Compile Include="ConfigReader.cs" />
<Compile Include="CrossDomainPolicy.cs" />
<Compile Include="Packet.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs">
@ -81,6 +86,7 @@
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Server.cs" />
<Compile Include="User.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View file

@ -13,6 +13,10 @@ namespace Horse_Isle_Server
if (ConfigReader.Debug)
Console.WriteLine("[DEBUG] " + text);
}
public static void WarnPrint(string text)
{
Console.WriteLine("[WARN] " + text);
}
public static void ErrorPrint(string text)
{
Console.WriteLine("[ERROR] " + text);

View file

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server
{
class Map
{
public static Bitmap MapData;
public static Bitmap oMapData;
public static int GetTileId(int x, int y, bool overlay)
{
if ((x > MapData.Width || x < 0) || (y > MapData.Height || y < 0)) // Outside map?
return 0x01;
if(overlay)
return oMapData.GetPixel(x,y).ToArgb() & Convert.ToInt32(0xFF000000);
else
return MapData.GetPixel(x, y).ToArgb() & Convert.ToInt32(0xFF000000);
}
public static void OpenMap()
{
if(!File.Exists(ConfigReader.MapFile) || !File.Exists(ConfigReader.OverlayMapFile))
{
Logger.ErrorPrint("Map file not found.");
return;
}
MapData = new Bitmap(ConfigReader.MapFile);
oMapData = new Bitmap(ConfigReader.MapFile);
}
}
}

View file

@ -0,0 +1,182 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server
{
class PacketBuilder
{
public const byte PACKET_TERMINATOR = 0x00;
public const byte PACKET_A_TERMINATOR = 0x0A;
public const byte PACKET_LOGIN = 0x7F;
public const byte PACKET_CHAT = 0x14;
public const byte PACKET_MOVE = 0x15;
public const byte PACKET_USERINFO = 0x81;
public const byte PACKET_WORLD = 0x7A;
private const byte CHAT_BOTTOM_LEFT = 0x14;
private const byte CHAT_BOTTOM_RIGHT = 0x15;
public const byte LOGIN_INVALID_USER_PASS = 0x15;
public const byte LOGIN_SUCCESS = 0x14;
public static byte[] CreateLoginPacket(bool Success)
{
MemoryStream ms = new MemoryStream();
ms.WriteByte(PACKET_LOGIN);
if (Success)
ms.WriteByte(LOGIN_SUCCESS);
else
ms.WriteByte(LOGIN_INVALID_USER_PASS);
ms.WriteByte(PACKET_TERMINATOR);
ms.Seek(0x00, SeekOrigin.Begin);
byte[] Packet = ms.ToArray();
ms.Dispose();
return Packet;
}
public static byte[] CreateMovementPacket(int x, int y,int charId, int facing, int direction, bool walk)
{
// Header information
MemoryStream ms = new MemoryStream();
ms.WriteByte(PACKET_MOVE);
ms.WriteByte((byte)((x / 64) + 20)); //1
ms.WriteByte((byte)((x % 64) + 20)); //2
ms.WriteByte((byte)((y / 64) + 20)); //3
ms.WriteByte((byte)((y % 64) + 20)); //4
ms.WriteByte((byte)(facing + 20)); //5
ms.WriteByte((byte)((charId / 64) + 20)); //6
ms.WriteByte((byte)((charId % 64) + 20)); //7
ms.WriteByte((byte)(direction + 20)); //8
ms.WriteByte((byte)(Convert.ToInt32(walk) + 20)); //9
// Map Data
if (direction >= 20)
{
direction -= 20;
}
if (direction == 4)
{
for(int rely = y - 3; rely < rely + 9; rely++)
{
for (int relx = x - 2; relx < relx + 12; relx++)
{
int tileId = Map.GetTileId(relx, rely, false);
int otileId = Map.GetTileId(relx, rely, true);
if (tileId == 290)
tileId -= 100;
if(otileId == 290)
otileId -= 100;
ms.WriteByte((byte)tileId);
ms.WriteByte((byte)otileId);
}
}
}
ms.WriteByte(PACKET_TERMINATOR);
ms.Seek(0x00, SeekOrigin.Begin);
byte[] Packet = ms.ToArray();
ms.Dispose();
return Packet;
}
public static byte[] CreateChat(string formattedText, byte chatWindow)
{
byte[] strBytes = Encoding.UTF8.GetBytes(formattedText);
MemoryStream ms = new MemoryStream();
ms.WriteByte(PACKET_CHAT);
ms.WriteByte(chatWindow);
ms.Write(strBytes, 0x00, strBytes.Length);
ms.WriteByte(PACKET_TERMINATOR);
ms.Seek(0x00, SeekOrigin.Begin);
byte[] Packet = ms.ToArray();
ms.Dispose();
return Packet;
}
public static byte[] CreateLoginMessage(string username)
{
string formattedStr = Gamedata.NewUserMessage.Replace("%USERNAME%", username);
return CreateChat(formattedStr,CHAT_BOTTOM_RIGHT);
}
public static byte[] CreateWorldData(int gameTime, int gameDay, int gameYear, string weather)
{
byte[] strBytes = Encoding.UTF8.GetBytes(weather);
MemoryStream ms = new MemoryStream();
ms.WriteByte(PACKET_WORLD);
ms.WriteByte((byte)((gameTime / 64) + 20));
ms.WriteByte((byte)((gameTime % 64) + 20));
ms.WriteByte((byte)((gameDay / 64) + 20));
ms.WriteByte((byte)((gameDay % 64) + 20));
ms.WriteByte((byte)((gameYear / 64) + 20));
ms.WriteByte((byte)((gameYear % 64) + 20));
ms.Write(strBytes,0x00, strBytes.Length);
ms.WriteByte(PACKET_TERMINATOR);
ms.Seek(0x00, SeekOrigin.Begin);
byte[] Packet = ms.ToArray();
ms.Dispose();
return Packet;
}
public static byte[] CreateUserInfo(Client client)
{
MemoryStream ms = new MemoryStream();
if(!client.LoggedIn)
throw new Exception("Client is not logged in.");
User user = client.LoggedinUser;
byte[] MovementPacket = CreateMovementPacket(user.X, user.Y, user.CharacterId, 2, 4, false);
ms.Write(MovementPacket, 0x00, MovementPacket.Length);
byte[] LoginMessage = CreateLoginMessage(user.Username);
ms.Write(LoginMessage, 0x00, LoginMessage.Length);
World.Time time = World.GetGameTime();
int timestamp = time.hours * 60;
timestamp += time.minutes;
byte[] WorldData = CreateWorldData(timestamp, time.days, time.year, World.GetWeather());
ms.Write(WorldData, 0x00, LoginMessage.Length);
ms.Seek(0x00, SeekOrigin.Begin);
byte[] Packet = ms.ToArray();
ms.Dispose();
return Packet;
}
}
}

View file

@ -1,11 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.IO;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server
{
@ -15,7 +9,12 @@ namespace Horse_Isle_Server
{
Directory.SetCurrentDirectory(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));
ConfigReader.OpenConfig();
CrossDomainPolicy.GetPolicy();
Database.OpenDatabase();
Map.OpenMap();
Gamedata.ReadGamedata();
Server.StartServer();
}
}
}

View file

@ -1,3 +1,3 @@
<cross-domain-policy>
<allow-access-from domain="*" to-ports="1080" secure="false"/>
<allow-access-from domain="*" to-ports="12321" secure="false"/>
</cross-domain-policy>

View file

@ -2,8 +2,8 @@
# Ip address the server will bind to (default: 0.0.0.0 ALL INTERFACES)
ip=0.0.0.0
# Port the server will bind to (default: 1080)
port=1080
# Port the server will bind to (default: 12321)
port=12321
# MariaDB Database
db_ip=127.0.0.1
@ -16,8 +16,14 @@ db_port=3306
map=MapData.bmp
overlaymap=oMapData.bmp
# Game Data JSON
gamedata=gamedata.json
# Cross-Domain Policy File
crossdomain=CrossDomainPolicy.xml
# Red Text Stating "Todays Note:"
motd=April 11, 2020. New breed, Camarillo White Horse. Two new quests.
# Should print debug logs
debug=false

View file

@ -19,36 +19,62 @@ namespace Horse_Isle_Server
Logger.DebugPrint("Cross-Domain-Policy request received from: " + sender.RemoteIp);
byte[] crossDomainPolicyResponse = CrossDomainPolicy.GetPolicy(); // Generate response packet
sender.SendPacket(crossDomainPolicyResponse); // Send to client.
}
public static void OnLoginRequest(Client sender, byte[] packet)
{
Logger.DebugPrint("Login request received from: " + sender.RemoteIp);
string loginRequestString = Encoding.UTF8.GetString(packet).Substring(1);
if (!loginRequestString.Contains('|'))
if (!loginRequestString.Contains('|') || packet.Length < 3)
{
Logger.ErrorPrint(sender.RemoteIp + " Sent an invalid login request" + loginRequestString);
Logger.ErrorPrint(sender.RemoteIp + " Sent an invalid login request");
return;
}
string[] loginParts = loginRequestString.Split('|');
if(loginParts.Length < 3)
if(packet[1] != PacketBuilder.PACKET_A_TERMINATOR)
{
Logger.ErrorPrint(sender.RemoteIp + " Sent a login request of invalid length. " + loginRequestString);
return;
string[] loginParts = loginRequestString.Split('|');
if (loginParts.Length < 3)
{
Logger.ErrorPrint(sender.RemoteIp + " Sent a login request of invalid length. " + loginRequestString);
return;
}
int version = int.Parse(loginParts[0]);
string encryptedUsername = loginParts[1];
string encryptedPassword = loginParts[2];
string username = Authentication.DecryptLogin(encryptedUsername);
string password = Authentication.DecryptLogin(encryptedPassword);
if (Authentication.CheckPassword(username, password))
{
// Obtain user information
int userId = Database.GetUserid(username);
sender.Login(userId);
byte[] ResponsePacket = PacketBuilder.CreateLoginPacket(true);
sender.SendPacket(ResponsePacket);
}
else
{
Logger.WarnPrint(sender.RemoteIp + " Attempted to login to: " + username + " with incorrect password " + password);
byte[] ResponsePacket = PacketBuilder.CreateLoginPacket(false);
sender.SendPacket(ResponsePacket);
}
}
else
{
if(!sender.LoggedIn)
{
Logger.ErrorPrint(sender.RemoteIp + " Requested user information when not logged in.");
return;
}
}
int version = int.Parse(loginParts[0]);
string encryptedUsername = loginParts[1];
string encryptedPassword = loginParts[2];
string username = Authentication.DecryptLogin(encryptedUsername);
string password = Authentication.DecryptLogin(encryptedPassword);
if(Authentication.CheckPassword(username, password))
{
}
}
public static void StartServer()
{

View file

@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server
{
class User
{
public int Id;
public string Username;
public bool Administrator;
public bool Moderator;
public bool NewPlayer = false;
public string ProfilePage {
get
{
return profilePage;
}
set
{
Database.SetPlayerProfile(value, Id);
profilePage = value;
}
}
public int Money
{
get
{
return money;
}
set
{
Database.SetPlayerBankMoney(value, Id);
money = value;
}
}
public int BankMoney
{
get
{
return bankMoney;
}
set
{
Database.SetPlayerBankMoney(value, Id);
bankMoney = value;
}
}
public short X
{
get
{
return x;
}
set
{
Database.SetPlayerX(value, Id);
x = value;
}
}
public short Y
{
get
{
return y;
}
set
{
Database.SetPlayerY(value, Id);
y = value;
}
}
public short CharacterId
{
get
{
return charId;
}
set
{
Database.SetPlayerCharId(value, Id);
charId = value;
}
}
private int charId;
private string profilePage;
private int x;
private int y;
private int money;
private int bankMoney;
public User(int UserId)
{
if (!Database.CheckUserExist(UserId))
throw new KeyNotFoundException("User " + UserId + " not found in database!");
if (!Database.CheckUserExtExists(UserId))
{
Database.CreateUserExt(UserId);
NewPlayer = true;
}
Id = UserId;
Username = Database.GetUsername(UserId);
Administrator = Database.CheckUserIsAdmin(Username);
Moderator = Database.CheckUserIsModerator(Username);
x = Database.GetPlayerX(UserId);
y = Database.GetPlayerY(UserId);
money = Database.GetPlayerMoney(UserId);
bankMoney = Database.GetPlayerBankMoney(UserId);
profilePage = Database.GetPlayerProfile(UserId);
}
}
}

View file

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server
{
class World
{
public static int ServerStartTime;
public const int MINUTE = 4320;
public static int GetGameDay()
{
int epoch = Database.GetServerCreationTime();
DateTime serverCreationTime = DateTimeOffset.FromUnixTimeSeconds(epoch).DateTime;
DateTime currentTime = DateTime.Now;
TimeSpan difference = (currentTime.Date - currentTime.Date);
Int64 totalMilis = Convert.ToInt32(difference.TotalMilliseconds);
Int64 gameMinutes = totalMilis / 4320;
return;
}
}
}

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MySqlConnector" version="1.0.1" targetFramework="net48" />
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net48" />
<package id="System.Buffers" version="4.4.0" targetFramework="net48" />
<package id="System.Memory" version="4.5.0" targetFramework="net48" />
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net48" />