diff --git a/Horse Isle Server/Horse Isle Server/Client.cs b/Horse Isle Server/Horse Isle Server/Client.cs
index dab881d..68460f4 100644
--- a/Horse Isle Server/Horse Isle Server/Client.cs
+++ b/Horse Isle Server/Horse Isle Server/Client.cs
@@ -20,10 +20,6 @@ namespace Horse_Isle_Server
private Thread recvPackets;
- private const byte PACKET_LOGIN = 0x7F;
- private const byte PACKET_CHAT = 0x14;
- private const byte PACKET_MOVE = 0x15;
- private const byte PACKET_USERINFO = 0x81;
public void Login(int id)
{
@@ -88,7 +84,7 @@ namespace Horse_Isle_Server
}
switch(identifier)
{
- case PACKET_LOGIN:
+ case PacketBuilder.PACKET_LOGIN:
Server.OnLoginRequest(this,Packet);
break;
}
diff --git a/Horse Isle Server/Horse Isle Server/Database.cs b/Horse Isle Server/Horse Isle Server/Database.cs
index 4128558..650d547 100644
--- a/Horse Isle Server/Horse Isle Server/Database.cs
+++ b/Horse Isle Server/Horse Isle Server/Database.cs
@@ -14,8 +14,9 @@ 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)";
+ string ExtTable = "CREATE TABLE UserExt(Id INT, X INT, Y INT, Money INT, BankBalance BIGINT,ProfilePage Text(1028), CharId INT)";
+ string MailTable = "CREATE TABLE Mailbox(IdTo INT, PlayerFrom TEXT(16),Subject TEXT(128), Message Text(1028), TimeSent INT)";
+ string WorldTable = "CREATE TABLE World(TimeStarted INT, Weather TEXT(64))";
try
{
@@ -40,6 +41,19 @@ namespace Horse_Isle_Server
Logger.WarnPrint(e.Message);
};
+ try
+ {
+
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = MailTable;
+ sqlCommand.ExecuteNonQuery();
+ }
+ catch (Exception e)
+ {
+ Logger.WarnPrint(e.Message);
+ };
+
+
try
{
@@ -105,7 +119,35 @@ namespace Horse_Isle_Server
throw new KeyNotFoundException("Username " + username + " not found in database.");
}
}
-
+
+ public static int CheckMailcount(int id)
+ {
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "SELECT COUNT(1) FROM Mailbox WHERE IdTo=@id";
+ sqlCommand.Parameters.AddWithValue("@id", id);
+ sqlCommand.Prepare();
+
+ Int32 count = Convert.ToInt32(sqlCommand.ExecuteScalar());
+ return count;
+ }
+
+ public static void AddMail(int toId, string fromName, string subject, string message)
+ {
+ MySqlCommand sqlCommand = db.CreateCommand();
+ int epoch = (int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
+
+ sqlCommand.CommandText = "INSERT INTO Mailbox VALUES(@toId,@from,@subject,@message,@time)";
+ sqlCommand.Parameters.AddWithValue("@toId", toId);
+ sqlCommand.Parameters.AddWithValue("@from", fromName);
+ sqlCommand.Parameters.AddWithValue("@subject", subject);
+ sqlCommand.Parameters.AddWithValue("@mesasge", message);
+ sqlCommand.Parameters.AddWithValue("@time", epoch);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+
+
+ }
+
public static bool CheckUserExist(int id)
{
MySqlCommand sqlCommand = db.CreateCommand();
diff --git a/Horse Isle Server/Horse Isle Server/Horse Isle Server.csproj b/Horse Isle Server/Horse Isle Server/Horse Isle Server.csproj
index dfccb2f..09619eb 100644
--- a/Horse Isle Server/Horse Isle Server/Horse Isle Server.csproj
+++ b/Horse Isle Server/Horse Isle Server/Horse Isle Server.csproj
@@ -50,6 +50,7 @@
..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll
+
..\packages\System.Memory.4.5.0\lib\netstandard2.0\System.Memory.dll
@@ -77,7 +78,8 @@
-
+
+
@@ -87,6 +89,7 @@
+
diff --git a/Horse Isle Server/Horse Isle Server/Mailbox.cs b/Horse Isle Server/Horse Isle Server/Mailbox.cs
new file mode 100644
index 0000000..d6d851a
--- /dev/null
+++ b/Horse Isle Server/Horse Isle Server/Mailbox.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Horse_Isle_Server
+{
+ class Mailbox
+ {
+ private User baseUser;
+ public int MailCount;
+
+ public Mailbox(User user)
+ {
+ MailCount = Database.CheckMailcount(user.Id);
+ baseUser = user;
+ }
+ }
+}
diff --git a/Horse Isle Server/Horse Isle Server/PacketBuilder.cs b/Horse Isle Server/Horse Isle Server/PacketBuilder.cs
index 728e114..2c2f6c6 100644
--- a/Horse Isle Server/Horse Isle Server/PacketBuilder.cs
+++ b/Horse Isle Server/Horse Isle Server/PacketBuilder.cs
@@ -19,7 +19,7 @@ namespace Horse_Isle_Server
public const byte PACKET_MOVE = 0x15;
public const byte PACKET_USERINFO = 0x81;
public const byte PACKET_WORLD = 0x7A;
-
+ public const byte PACKET_BASE_STATS = 0x7B;
private const byte CHAT_BOTTOM_LEFT = 0x14;
private const byte CHAT_BOTTOM_RIGHT = 0x15;
@@ -152,6 +152,55 @@ namespace Horse_Isle_Server
return Packet;
}
+
+ public static byte[] CreateBaseStats(int money, int playerCount, int mail)
+ {
+ byte[] moneyStrBytes = Encoding.UTF8.GetBytes(money.ToString());
+ byte[] playerStrBytes = Encoding.UTF8.GetBytes(playerCount.ToString());
+ byte[] mailStrBytes = Encoding.UTF8.GetBytes(mail.ToString());
+
+ MemoryStream ms = new MemoryStream();
+ ms.WriteByte(PACKET_BASE_STATS);
+ ms.Write(moneyStrBytes, 0x00, moneyStrBytes.Length);
+ ms.WriteByte((byte)'|');
+ ms.Write(playerStrBytes, 0x00, playerStrBytes.Length);
+ ms.WriteByte((byte)'|');
+ ms.Write(mailStrBytes, 0x00, mailStrBytes.Length);
+ ms.WriteByte((byte)'|');
+ ms.WriteByte(PACKET_TERMINATOR);
+
+ ms.Seek(0x00, SeekOrigin.Begin);
+ byte[] Packet = ms.ToArray();
+ ms.Dispose();
+
+ return Packet;
+ }
+ public static byte[] CreateSecCode(byte[] SecCodeSeed, int SecCodeInc, bool Admin, bool Moderator)
+ {
+ MemoryStream ms = new MemoryStream();
+ ms.WriteByte(PACKET_USERINFO);
+
+ ms.WriteByte((byte)(SecCodeSeed[0] + 33));
+ ms.WriteByte((byte)(SecCodeSeed[1] + 33));
+ ms.WriteByte((byte)(SecCodeSeed[2] + 33));
+ ms.WriteByte((byte)(SecCodeInc + 33));
+
+ char userType = 'N'; // Normal?
+ if (Moderator)
+ userType = 'M';
+ if (Admin)
+ userType = 'A';
+
+ ms.WriteByte((byte)userType);
+ 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();
@@ -172,6 +221,13 @@ namespace Horse_Isle_Server
byte[] WorldData = CreateWorldData(timestamp, time.days, time.year, World.GetWeather());
ms.Write(WorldData, 0x00, LoginMessage.Length);
+ byte[] SecCodePacket = CreateSecCode(user.SecCodeSeeds, user.SecCodeInc, user.Administrator, user.Moderator);
+ ms.Write(SecCodePacket, 0x00, SecCodePacket.Length);
+
+ byte[] BaseStatsPacketData = CreateBaseStats(user.Money, Server.GetNumberOfPlayers(), user.MailBox.MailCount);
+ ms.Write(BaseStatsPacketData, 0x00, BaseStatsPacketData.Length);
+
+
ms.Seek(0x00, SeekOrigin.Begin);
byte[] Packet = ms.ToArray();
ms.Dispose();
diff --git a/Horse Isle Server/Horse Isle Server/Program.cs b/Horse Isle Server/Horse Isle Server/Program.cs
index 074a0dd..1d9db89 100644
--- a/Horse Isle Server/Horse Isle Server/Program.cs
+++ b/Horse Isle Server/Horse Isle Server/Program.cs
@@ -1,4 +1,5 @@
-using System.IO;
+using System;
+using System.IO;
using System.Reflection;
namespace Horse_Isle_Server
diff --git a/Horse Isle Server/Horse Isle Server/Server.cs b/Horse Isle Server/Horse Isle Server/Server.cs
index 307b81c..45b716e 100644
--- a/Horse Isle Server/Horse Isle Server/Server.cs
+++ b/Horse Isle Server/Horse Isle Server/Server.cs
@@ -76,6 +76,17 @@ namespace Horse_Isle_Server
}
}
+
+ public static int GetNumberOfPlayers()
+ {
+ int count = 0;
+ foreach(Client client in ConnectedClients)
+ {
+ if (client.LoggedIn)
+ count++;
+ }
+ return count;
+ }
public static void StartServer()
{
ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
diff --git a/Horse Isle Server/Horse Isle Server/User.cs b/Horse Isle Server/Horse Isle Server/User.cs
index 1eccb2d..80b1f06 100644
--- a/Horse Isle Server/Horse Isle Server/User.cs
+++ b/Horse Isle Server/Horse Isle Server/User.cs
@@ -13,6 +13,7 @@ namespace Horse_Isle_Server
public bool Administrator;
public bool Moderator;
public bool NewPlayer = false;
+ public Mailbox MailBox;
public string ProfilePage {
get
@@ -52,7 +53,7 @@ namespace Horse_Isle_Server
}
}
- public short X
+ public int X
{
get
{
@@ -65,7 +66,7 @@ namespace Horse_Isle_Server
}
}
- public short Y
+ public int Y
{
get
{
@@ -78,7 +79,7 @@ namespace Horse_Isle_Server
}
}
- public short CharacterId
+ public int CharacterId
{
get
{
@@ -98,6 +99,28 @@ namespace Horse_Isle_Server
private int money;
private int bankMoney;
+ public byte[] SecCodeSeeds = new byte[3];
+ public int SecCodeInc = 0;
+ public int SecCodeCount = 0;
+
+
+ public byte[] GenerateSecCode()
+ {
+ var i = 0;
+ SecCodeCount++;
+ SecCodeSeeds[SecCodeCount % 3] = (byte)(SecCodeSeeds[SecCodeCount % 3] + SecCodeInc);
+ SecCodeSeeds[SecCodeCount % 3] = (byte)(SecCodeSeeds[SecCodeCount % 3] % 92);
+ i = SecCodeSeeds[0] + SecCodeSeeds[1] * SecCodeSeeds[2] - SecCodeSeeds[1];
+ i = Math.Abs(i);
+ i = i % 92;
+
+ byte[] SecCode = new byte[4];
+ SecCode[0] = (byte)(SecCodeSeeds[0] + 33);
+ SecCode[1] = (byte)(SecCodeSeeds[1] + 33);
+ SecCode[2] = (byte)(SecCodeSeeds[2] + 33);
+ SecCode[3] = (byte)(i + 33);
+ return SecCode;
+ }
public User(int UserId)
{
@@ -118,11 +141,23 @@ namespace Horse_Isle_Server
x = Database.GetPlayerX(UserId);
y = Database.GetPlayerY(UserId);
+ charId = Database.GetPlayerCharId(UserId);
money = Database.GetPlayerMoney(UserId);
bankMoney = Database.GetPlayerBankMoney(UserId);
-
+
profilePage = Database.GetPlayerProfile(UserId);
+
+ MailBox = new Mailbox(this);
+
+ // Generate SecCodes
+
+ Random rng = new Random();
+ SecCodeSeeds[0] = (byte)rng.Next(0, 255 - 33);
+ SecCodeSeeds[1] = (byte)rng.Next(0, 255 - 33);
+ SecCodeSeeds[2] = (byte)rng.Next(0, 255 - 33);
+ SecCodeInc = (byte)rng.Next(0, 255 - 33);
+
}
}
}
diff --git a/Horse Isle Server/Horse Isle Server/World.cs b/Horse Isle Server/Horse Isle Server/World.cs
index afe2505..f585fc6 100644
--- a/Horse Isle Server/Horse Isle Server/World.cs
+++ b/Horse Isle Server/Horse Isle Server/World.cs
@@ -6,13 +6,20 @@ using System.Threading.Tasks;
namespace Horse_Isle_Server
{
+
class World
{
- public static int ServerStartTime;
+ public struct Time
+ {
+ public int minutes;
+ public int hours;
+ public int days;
+ public int year;
+ }
public const int MINUTE = 4320;
- public static int GetGameDay()
+ public static Time GetGameTime()
{
int epoch = Database.GetServerCreationTime();
DateTime serverCreationTime = DateTimeOffset.FromUnixTimeSeconds(epoch).DateTime;
@@ -20,13 +27,26 @@ namespace Horse_Isle_Server
TimeSpan difference = (currentTime.Date - currentTime.Date);
- Int64 totalMilis = Convert.ToInt32(difference.TotalMilliseconds);
+ int totalMilis = Convert.ToInt32(difference.TotalMilliseconds);
- Int64 gameMinutes = totalMilis / 4320;
+ int gameMinutes = totalMilis / MINUTE;
+ int gameHours = (totalMilis / MINUTE * 600);
+ int gameDays = (totalMilis / (MINUTE * 60) * 24);
+ int gameYears = ((totalMilis / (MINUTE * 60) * 24)*365);
+ Time time = new Time();
+ time.days = gameDays;
+ time.year = gameYears;
+ time.minutes = gameMinutes;
+ time.hours = gameHours;
- return;
+ return time;
+ }
+
+ public static string GetWeather()
+ {
+ return Database.GetWorldWeather();
}
}
}
diff --git a/Horse Isle Server/Horse Isle Server/Resources/gamedata.json b/gamedata.json
similarity index 96%
rename from Horse Isle Server/Horse Isle Server/Resources/gamedata.json
rename to gamedata.json
index 5c5942d..84d7437 100644
--- a/Horse Isle Server/Horse Isle Server/Resources/gamedata.json
+++ b/gamedata.json
@@ -1,7 +1,10 @@
{"messages":{
- "login_message":"Welcome to the land of Horse Isle, %USERNAME%!!",
+ "login_format":"Welcome to the land of Horse Isle, %USERNAME%!!",
"motd_format":"Today's Note: %NOTE%",
- "global_chat":"%USERNAME%: %MESSAGE"
+ "mail_received":"A message has been sent to you from another player. It is in your inventory now.",
+ "global_format":"%USERNAME%: %MESSAGE",
+ "area_format":"You are on %AREA% ",
+ "nothing_message":"
^LYou see nothing on the ground of interest.^R1"
},
"new_user":{
"starting_message":"Welcome Newest Rider of Horse Isle!
Start by talking to Welcome Willy in the cabin. Click the TALK button by his name in the right hand window. He will know the location of a buried treasure on this island! Move to the spot he describes using the arrow keys. Then Click the WRENCH Icon at the lower right.",
diff --git a/notes.txt b/notes.txt
new file mode 100644
index 0000000..2e32f1b
--- /dev/null
+++ b/notes.txt
@@ -0,0 +1,2 @@
+Mail: Reading a Mail Message from Player
By: SilicaAndPina (DATE:Sep 29, 2020 6:19am) :
Noire
hi!
^T5To get rid of message:^B4Z248835242^R5^M^Z"
+Earton Town Hall: Earton Town Hall
The little post office here can deliver a message to someone on Horse Isle. Postage is $3 per message.^T5Write a message to another player?^D2|COMPOSE^R1^LAlso, the hall has records on several subjects:^R1^T4View current Horses up for Sale^D29|AUTOSELL HORSES^R1^T4View top valued ranches^D14|RANCH RECORDS^R1^T4View richest players^D15|MONEY RECORDS^R1^T4View top spoiled horses^D61|SPOILED HORSES^R1^T4View most adventurous players^D16|QUEST RECORDS^R1^T4View most experienced players^D17|EXPER RECORDS^R1^T4View most active minigamers^D18|GAMES RECORDS^R1^T4View top players' horses^D19|HORSE RECORDS^R1^X^Z