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)