diff --git a/DataCollection/gamedata.json b/DataCollection/gamedata.json
index 2757456..b8bcbbe 100755
--- a/DataCollection/gamedata.json
+++ b/DataCollection/gamedata.json
@@ -8,7 +8,6 @@
"profile_save":"Your profile changes were saved.",
"private_notes_save":"Saved Private Notes.",
"buddy_request":"Attempting to Add Buddy. The other player must click ADD BUDDY as well. (Many players reserve this for just a couple players so don't feel insulted if they do not).",
- "drawing_notice":"Drawing not sent to other players when you are not a subscriber.",
"click_nothing_message":"Nothing interesting here...",
"playtime_timeout":"You have run out of playtime for now. In one minute you will be disconnected. You gain one minute of playtime every 8 minutes. Please come back later!",
"random_movement":"You are sooo %STAT%. You wander dizzily in a different direction.",
diff --git a/Horse Isle Server/HorseIsleServer/Game/Items/DroppedItems.cs b/Horse Isle Server/HorseIsleServer/Game/Items/DroppedItems.cs
index 8d6b135..e4bebcc 100755
--- a/Horse Isle Server/HorseIsleServer/Game/Items/DroppedItems.cs
+++ b/Horse Isle Server/HorseIsleServer/Game/Items/DroppedItems.cs
@@ -169,7 +169,7 @@ namespace HISP.Game.Items
if (item.SpawnParamaters.SpawnOnTileType == TileType)
{
- if (GetItemsAt(tryX, tryY).Length > 26) // Max here
+ if (GetItemsAt(tryX, tryY).Length > 25) // Max items in one tile.
continue;
ItemInstance instance = new ItemInstance(item.Id);
@@ -206,7 +206,7 @@ namespace HISP.Game.Items
if (Map.CheckPassable(spawnOn.X, spawnOn.Y))
{
- if (GetItemsAt(spawnOn.X, spawnOn.Y).Length > 26) // Max here
+ if (GetItemsAt(spawnOn.X, spawnOn.Y).Length > 25) // Max items in one tile.
continue;
ItemInstance instance = new ItemInstance(item.Id);
@@ -270,7 +270,7 @@ namespace HISP.Game.Items
if (Map.CheckPassable(tryX, tryY))
{
- if (GetItemsAt(tryX, tryY).Length > 26) // Max here
+ if (GetItemsAt(tryX, tryY).Length > 25) // Max here
continue;
ItemInstance instance = new ItemInstance(item.Id);
@@ -297,13 +297,7 @@ namespace HISP.Game.Items
while (true)
{
- // Pick a random isle:
- //int isleId = GameServer.RandomNumberGenerator.Next(0, World.Isles.Count);
- //World.Isle isle = World.Isles[isleId];
-
- // Pick a random location inside the isle
- //int tryX = GameServer.RandomNumberGenerator.Next(isle.StartX, isle.EndX);
- //int tryY = GameServer.RandomNumberGenerator.Next(isle.StartY, isle.EndY);
+ // Pick a random location:
int tryX = GameServer.RandomNumberGenerator.Next(0, Map.Width);
int tryY = GameServer.RandomNumberGenerator.Next(0, Map.Height);
@@ -317,7 +311,7 @@ namespace HISP.Game.Items
if (item.SpawnParamaters.SpawnOnTileType == TileType)
{
- if (GetItemsAt(tryX, tryY).Length > 26) // Max here
+ if (GetItemsAt(tryX, tryY).Length > 25) // Max here
continue;
ItemInstance instance = new ItemInstance(item.Id);
diff --git a/Horse Isle Server/HorseIsleServer/Game/Messages.cs b/Horse Isle Server/HorseIsleServer/Game/Messages.cs
index 1157584..ed54759 100755
--- a/Horse Isle Server/HorseIsleServer/Game/Messages.cs
+++ b/Horse Isle Server/HorseIsleServer/Game/Messages.cs
@@ -525,6 +525,8 @@ namespace HISP.Game
public static string DrawingContentsLoadedFromSlotFormat;
public static string DrawingPlzClearLoad;
public static string DrawingPlzClearDraw;
+ public static string DrawingNotSentNotSubscribed;
+ public static string DrawingCannotLoadNotSubscribed;
// Birckpoet
public static string LastPoetFormat;
diff --git a/Horse Isle Server/HorseIsleServer/Game/SwfModules/Drawingroom.cs b/Horse Isle Server/HorseIsleServer/Game/SwfModules/Drawingroom.cs
index f9db252..b7eb5c2 100644
--- a/Horse Isle Server/HorseIsleServer/Game/SwfModules/Drawingroom.cs
+++ b/Horse Isle Server/HorseIsleServer/Game/SwfModules/Drawingroom.cs
@@ -9,6 +9,15 @@ namespace HISP.Game.SwfModules
{
class Drawingroom
{
+ private static List drawingRooms = new List();
+ public static Drawingroom[] DrawingRooms
+ {
+ get
+ {
+ return drawingRooms.ToArray();
+ }
+ }
+
private string drawing;
public string Drawing
{
@@ -32,11 +41,43 @@ namespace HISP.Game.SwfModules
public int Id;
public Drawingroom(int roomId)
{
+
if (!Database.DrawingRoomExists(roomId))
+ {
Database.CreateDrawingRoom(roomId);
+ Database.SetLastPlayer("D" + roomId.ToString(), -1);
+ }
+
drawing = Database.GetDrawingRoomDrawing(roomId);
Id = roomId;
+ drawingRooms.Add(this);
+ }
+ public static void LoadAllDrawingRooms()
+ {
+ // iterate over every special tile
+ foreach(World.SpecialTile tile in World.SpecialTiles)
+ {
+ if(tile.Code != null)
+ {
+ if (tile.Code.StartsWith("MULTIROOM-D"))
+ {
+ int roomId = int.Parse(tile.Code.Substring(11));
+ Logger.InfoPrint("Loading Drawing Room ID: " + roomId.ToString());
+ Drawingroom room = new Drawingroom(roomId);
+ }
+ }
+
+ }
+ }
+ public static Drawingroom GetDrawingRoomById(int id)
+ {
+ foreach(Drawingroom room in DrawingRooms)
+ {
+ if (room.Id == id)
+ return room;
+ }
+ throw new KeyNotFoundException("Room with id: " + id + " not found.");
}
}
diff --git a/Horse Isle Server/HorseIsleServer/Player/User.cs b/Horse Isle Server/HorseIsleServer/Player/User.cs
index 885948b..e098eef 100755
--- a/Horse Isle Server/HorseIsleServer/Player/User.cs
+++ b/Horse Isle Server/HorseIsleServer/Player/User.cs
@@ -90,6 +90,9 @@ namespace HISP.Player
{
if (ConfigReader.AllUsersSubbed)
return true;
+
+ if (Administrator)
+ return true;
int Timestamp = Convert.ToInt32(new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds());
if(Timestamp > subscribedUntil && subscribed) // sub expired.
diff --git a/Horse Isle Server/HorseIsleServer/Program.cs b/Horse Isle Server/HorseIsleServer/Program.cs
index ac1b50d..b1a3a7a 100755
--- a/Horse Isle Server/HorseIsleServer/Program.cs
+++ b/Horse Isle Server/HorseIsleServer/Program.cs
@@ -22,6 +22,7 @@ namespace HISP
DroppedItems.Init();
WildHorse.Init();
Brickpoet.LoadPoetryRooms();
+ Drawingroom.LoadAllDrawingRooms();
Item.DoSpecialCases();
GameServer.StartServer();
diff --git a/Horse Isle Server/HorseIsleServer/Server/Database.cs b/Horse Isle Server/HorseIsleServer/Server/Database.cs
index d9de40d..81f8479 100755
--- a/Horse Isle Server/HorseIsleServer/Server/Database.cs
+++ b/Horse Isle Server/HorseIsleServer/Server/Database.cs
@@ -1129,7 +1129,60 @@ namespace HISP.Server
return drawing;
}
}
+ public static string LoadDrawingSlot3(int playerId)
+ {
+ if (!SavedDrawingsExist(playerId))
+ CreateSavedDrawings(playerId);
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "SELECT Drawing3 FROM SavedDrawings WHERE playerId=@playerId";
+ sqlCommand.Parameters.AddWithValue("@playerId", playerId);
+ sqlCommand.Prepare();
+ string drawing = sqlCommand.ExecuteScalar().ToString();
+
+ sqlCommand.Dispose();
+ return drawing;
+ }
+ }
+ public static string LoadDrawingSlot2(int playerId)
+ {
+ if (!SavedDrawingsExist(playerId))
+ CreateSavedDrawings(playerId);
+
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "SELECT Drawing2 FROM SavedDrawings WHERE playerId=@playerId";
+ sqlCommand.Parameters.AddWithValue("@playerId", playerId);
+ sqlCommand.Prepare();
+ string drawing = sqlCommand.ExecuteScalar().ToString();
+
+ sqlCommand.Dispose();
+ return drawing;
+ }
+ }
+ public static string LoadDrawingSlot1(int playerId)
+ {
+ if (!SavedDrawingsExist(playerId))
+ CreateSavedDrawings(playerId);
+
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "SELECT Drawing1 FROM SavedDrawings WHERE playerId=@playerId";
+ sqlCommand.Parameters.AddWithValue("@playerId", playerId);
+ sqlCommand.Prepare();
+ string drawing = sqlCommand.ExecuteScalar().ToString();
+
+ sqlCommand.Dispose();
+ return drawing;
+ }
+ }
public static void SaveDrawingSlot1(int playerId, string drawing)
{
if (!SavedDrawingsExist(playerId))
diff --git a/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs b/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs
index 3923011..3381144 100755
--- a/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs
+++ b/Horse Isle Server/HorseIsleServer/Server/GameDataJson.cs
@@ -897,6 +897,15 @@ namespace HISP.Server
Messages.PasswordNotice = gameData.messages.chat.password_included;
Messages.CapsNotice = gameData.messages.chat.caps_notice;
+ // Drawing Rooms
+ Messages.DrawingLastToDrawFormat = gameData.messages.meta.drawing_rooms.last_draw;
+ Messages.DrawingContentsSavedInSlotFormat = gameData.messages.meta.drawing_rooms.saved;
+ Messages.DrawingContentsLoadedFromSlotFormat = gameData.messages.meta.drawing_rooms.load;
+ Messages.DrawingPlzClearDraw = gameData.messages.meta.drawing_rooms.plz_clear_draw;
+ Messages.DrawingPlzClearLoad = gameData.messages.meta.drawing_rooms.plz_clear_load;
+ Messages.DrawingNotSentNotSubscribed = gameData.messages.meta.drawing_rooms.not_subscribed_draw;
+ Messages.DrawingCannotLoadNotSubscribed = gameData.messages.meta.drawing_rooms.not_subscribed_load;
+
// Brickpoet
Messages.LastPoetFormat = gameData.messages.meta.last_poet;
diff --git a/Horse Isle Server/HorseIsleServer/Server/GameServer.cs b/Horse Isle Server/HorseIsleServer/Server/GameServer.cs
index 7cd9cfa..0e83785 100755
--- a/Horse Isle Server/HorseIsleServer/Server/GameServer.cs
+++ b/Horse Isle Server/HorseIsleServer/Server/GameServer.cs
@@ -1623,6 +1623,212 @@ namespace HISP.Server
byte module = packet[1];
switch(module)
{
+ case PacketBuilder.SWFMODULE_DRAWINGROOM:
+ if(packet.Length < 3)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent invalid DRAWINGROOM packet (swf communication, WRONG SIZE)");
+ break;
+ }
+ if(packet[2] == PacketBuilder.DRAWINGROOM_GET_DRAWING)
+ {
+ if (packet.Length < 6)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent invalid DRAWINGROOM GET DRAWING packet (swf communication, WRONG SIZE)");
+ break;
+ }
+ int roomId = packet[3] - 40;
+ Drawingroom room;
+ try
+ {
+ room = Drawingroom.GetDrawingRoomById(roomId);
+ }
+ catch(KeyNotFoundException)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " tried to load an invalid drawing room: " + roomId);
+ break;
+ }
+ if(room.Drawing != "")
+ {
+ byte[] drawingPacket = PacketBuilder.CreateDrawingUpdatePacket(room.Drawing);
+ sender.SendPacket(drawingPacket);
+ }
+
+ }
+ else if(packet[2] == PacketBuilder.DRAWINGROOM_SAVE)
+ {
+ if (packet.Length < 5)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent invalid DRAWINGROOM GET DRAWING packet (swf communication, WRONG SIZE)");
+ break;
+ }
+
+ /*
+ * The lack of an if case for if the user isnt subscribed
+ * is NOT a bug thats just how pinto does it.
+ * you can save but not load if your subscribed. weird huh?
+ */
+
+ int roomId = packet[3] - 40;
+ Drawingroom room;
+ try
+ {
+ room = Drawingroom.GetDrawingRoomById(roomId);
+ }
+ catch (KeyNotFoundException)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " tried to load an invalid drawing room: " + roomId);
+ break;
+ }
+
+
+
+ if (!Database.SavedDrawingsExist(sender.LoggedinUser.Id))
+ Database.CreateSavedDrawings(sender.LoggedinUser.Id);
+
+ int slotNo = 0;
+ byte slot = packet[4];
+ switch (slot)
+ {
+ case 0x29: // Slot 1
+ Database.SaveDrawingSlot1(sender.LoggedinUser.Id, room.Drawing);
+ slotNo = 1;
+ break;
+ case 0x2A: // Slot 2
+ Database.SaveDrawingSlot2(sender.LoggedinUser.Id, room.Drawing);
+ slotNo = 2;
+ break;
+ case 0x2B: // Slot 3
+ Database.SaveDrawingSlot3(sender.LoggedinUser.Id, room.Drawing);
+ slotNo = 3;
+ break;
+ }
+
+ byte[] savedDrawingMessage = PacketBuilder.CreateChat(Messages.FormatDrawingRoomSaved(slotNo), PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(savedDrawingMessage);
+
+ break;
+ }
+ else if (packet[2] == PacketBuilder.DRAWINGROOM_LOAD)
+ {
+ if (packet.Length < 5)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent invalid DRAWINGROOM GET DRAWING packet (swf communication, WRONG SIZE)");
+ break;
+ }
+
+ if(!sender.LoggedinUser.Subscribed)
+ {
+ byte[] notSubscribedCantLoad = PacketBuilder.CreateChat(Messages.DrawingCannotLoadNotSubscribed, PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(notSubscribedCantLoad);
+ break;
+ }
+
+ int roomId = packet[3] - 40;
+ Drawingroom room;
+ try
+ {
+ room = Drawingroom.GetDrawingRoomById(roomId);
+ }
+ catch (KeyNotFoundException)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " tried to load an invalid drawing room: " + roomId);
+ break;
+ }
+
+ if (!Database.SavedDrawingsExist(sender.LoggedinUser.Id))
+ Database.CreateSavedDrawings(sender.LoggedinUser.Id);
+
+ int slotNo = 0;
+ byte slot = packet[4];
+ string drawingToAdd = "";
+ switch (slot)
+ {
+ case 0x29: // Slot 1
+ drawingToAdd = Database.LoadDrawingSlot1(sender.LoggedinUser.Id);
+ slotNo = 1;
+ break;
+ case 0x2A: // Slot 2
+ drawingToAdd = Database.LoadDrawingSlot2(sender.LoggedinUser.Id);
+ slotNo = 2;
+ break;
+ case 0x2B: // Slot 3
+ drawingToAdd = Database.LoadDrawingSlot3(sender.LoggedinUser.Id);
+ slotNo = 3;
+ break;
+ }
+
+ if (room.Drawing.Length + drawingToAdd.Length < 65535) // will this max out the db?
+ {
+ room.Drawing += drawingToAdd;
+ Database.SetLastPlayer("D" + room.Id.ToString(), sender.LoggedinUser.Id);
+ }
+ else
+ {
+ byte[] roomFullMessage = PacketBuilder.CreateChat(Messages.DrawingPlzClearLoad, PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(roomFullMessage);
+ break;
+ }
+
+ room.Drawing += drawingToAdd;
+ UpdateDrawingForAll(sender, drawingToAdd, true);
+
+ byte[] loadedDrawingMessage = PacketBuilder.CreateChat(Messages.FormatDrawingRoomLoaded(slotNo), PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(loadedDrawingMessage);
+
+ break;
+ }
+ else // Default action- draw line
+ {
+ if (packet.Length < 5)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent invalid DRAWINGROOM GET DRAWING packet (swf communication, WRONG SIZE)");
+ break;
+ }
+
+ if(!sender.LoggedinUser.Subscribed)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " Tried to draw while not subscribed.");
+ byte[] notSubscribedMessage = PacketBuilder.CreateChat(Messages.DrawingNotSentNotSubscribed, PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(notSubscribedMessage);
+ break;
+ }
+
+ int roomId = packet[2] - 40;
+ Drawingroom room;
+ try
+ {
+ room = Drawingroom.GetDrawingRoomById(roomId);
+ }
+ catch (KeyNotFoundException)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " tried to load an invalid drawing room: " + roomId);
+ break;
+ }
+
+ string packetStr = Encoding.UTF8.GetString(packet);
+
+ string drawing = packetStr.Substring(3, packetStr.Length - 5);
+ if (drawing.Contains("X")) // Clear byte
+ {
+ room.Drawing = "";
+ }
+ else if(room.Drawing.Length + drawing.Length < 65535) // will this max out the db?
+ {
+ room.Drawing += drawing;
+ Database.SetLastPlayer("D" + room.Id.ToString(), sender.LoggedinUser.Id);
+ }
+ else
+ {
+ byte[] roomFullMessage = PacketBuilder.CreateChat(Messages.DrawingPlzClearDraw, PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(roomFullMessage);
+ break;
+ }
+
+ UpdateDrawingForAll(sender, drawing, false);
+
+ }
+
+ break;
case PacketBuilder.SWFMODULE_BRICKPOET:
if(packet.Length < 5)
{
@@ -2691,7 +2897,7 @@ namespace HISP.Server
return;
}
- Logger.DebugPrint(sender.LoggedinUser.Username + " Clicked on tile: " + Map.GetTileId(x, y, false).ToString() + "(overlay: " + Map.GetTileId(x, y, true).ToString() + " at " + x.ToString() + "," + y.ToString());
+ Logger.DebugPrint(sender.LoggedinUser.Username + " Clicked on tile: " + Map.GetTileId(x, y, false).ToString() + "(overlay: " + Map.GetTileId(x, y, true).ToString() + ") at " + x.ToString() + "," + y.ToString());
// Get description of tile
@@ -3107,7 +3313,7 @@ namespace HISP.Server
{
InventoryItem itm = sender.LoggedinUser.Inventory.GetItemByRandomid(randomId);
ItemInstance instance = itm.ItemInstances[0];
- if(DroppedItems.GetItemsAt(sender.LoggedinUser.X, sender.LoggedinUser.Y).Length > 26)
+ if(DroppedItems.GetItemsAt(sender.LoggedinUser.X, sender.LoggedinUser.Y).Length > 25)
{
byte[] tileIsFullPacket = PacketBuilder.CreateChat(Messages.DroppedItemTileIsFull, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(tileIsFullPacket);
@@ -3892,6 +4098,23 @@ namespace HISP.Server
UpdateUserInfo(client.LoggedinUser);
}
+ public static void UpdateDrawingForAll(GameClient sender, string drawing, bool includingSender=false)
+ {
+
+ UpdateAreaForAll(sender.LoggedinUser.X, sender.LoggedinUser.Y);
+ User[] usersHere = GetUsersAt(sender.LoggedinUser.X, sender.LoggedinUser.Y, true, true);
+ foreach (User user in usersHere)
+ {
+ if(!includingSender)
+ if (user.Id == sender.LoggedinUser.Id)
+ continue;
+
+
+ byte[] patchDrawing = PacketBuilder.CreateDrawingUpdatePacket(drawing);
+ user.LoggedinClient.SendPacket(patchDrawing);
+
+ }
+ }
public static void UpdateHorseMenu(GameClient forClient, HorseInstance horseInst)
{
int TileID = Map.GetTileId(forClient.LoggedinUser.X, forClient.LoggedinUser.Y, false);
diff --git a/Horse Isle Server/HorseIsleServer/Server/PacketBuilder.cs b/Horse Isle Server/HorseIsleServer/Server/PacketBuilder.cs
index 6afcfa6..e799958 100755
--- a/Horse Isle Server/HorseIsleServer/Server/PacketBuilder.cs
+++ b/Horse Isle Server/HorseIsleServer/Server/PacketBuilder.cs
@@ -67,6 +67,11 @@ namespace HISP.Server
public const byte HORSE_CAUGHT = 0x1D;
public const byte SWFMODULE_BRICKPOET = 0x5A;
+ public const byte SWFMODULE_DRAWINGROOM = 0x5B;
+
+ public const byte DRAWINGROOM_GET_DRAWING = 0x14;
+ public const byte DRAWINGROOM_SAVE = 0x15;
+ public const byte DRAWINGROOM_LOAD = 0x16;
public const byte BRICKPOET_LIST_ALL = 0x14;
public const byte BRICKPOET_MOVE = 0x55;
@@ -148,8 +153,16 @@ namespace HISP.Server
public const byte DIRECTION_TELEPORT = 4;
public const byte DIRECTION_NONE = 10;
-
-
+ public static byte[] CreateDrawingUpdatePacket(string Drawing)
+ {
+ MemoryStream ms = new MemoryStream();
+ ms.WriteByte(PacketBuilder.PACKET_SWFMODULE);
+ byte[] drawingBytes = Encoding.UTF8.GetBytes(Drawing);
+ ms.Write(drawingBytes, 0x00, drawingBytes.Length);
+ ms.WriteByte(PACKET_TERMINATOR);
+ ms.Seek(0x00, SeekOrigin.Begin);
+ return ms.ToArray();
+ }
public static byte[] CreateBrickPoetMovePacket(Brickpoet.PoetryPeice peice)
{
@@ -817,7 +830,7 @@ namespace HISP.Server
ms.Seek(0x00, SeekOrigin.Begin);
byte[] Packet = ms.ToArray();
ms.Dispose();
-
+ Logger.InfoPrint("Sending load "+(char)type + swf + " packet");
return Packet;
}
public static byte[] CreateAnnouncement(string announcement)