diff --git a/DataCollection/gamedata.json b/DataCollection/gamedata.json
index 09b39ed..72d72d4 100644
--- a/DataCollection/gamedata.json
+++ b/DataCollection/gamedata.json
@@ -7,6 +7,8 @@
"profile_save":"Your profile changes were saved.",
"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.",
+ "grab_message":"You grabbed an object off the ground.",
+ "grab_all_message":"You grabbed all objects off the ground.",
"tag":{
"for_sender":"TAG!! %USERNAME% is now it! (tagged by %TAGGER%) [%AMOUNT% buds]",
"for_others":"TAG!! %USERNAME% is now it! (tagged by %TAGGER%)"
@@ -34,12 +36,19 @@
"area_format":" in %AREA%",
"location_format":" You are%META% ",
"tile_format":"%TILENAME%",
- "nothing_message":"^LYou see nothing on the ground of interest.^R1",
- "transport_format":"^LTransport via %METHOD% to %PLACE%^R1^I%ICON%^T4Trip Costs $%COST% one way. ^B1M%XY%^BY%ID%",
+
+ "transport_format":"^R1^LTransport via %METHOD% to %PLACE%^R1^I%ICON%^T4Trip Costs $%COST% one way. ^B1M%XY%^BY%ID%",
"exit_this_place":"^X",
"end_of_meta":"^Z",
"back_to_map":"^M",
- "inventory_format":"^ATYour Inventory^HYou are carrying the following %ITEMCOUNT% different items: (%MAXITEMS% max)",
+ "long_full_line":"^L",
+ "inventory_format":"^ATYour Inventory^HYou are carrying the following %ITEMCOUNT% different items: (%% max)",
+ "dropped_items":{
+ "nothing_message":"^LYou see nothing on the ground of interest.^R1",
+ "items_message":"^LYou see the following on the ground:^R1",
+ "item_format":"^I%ICONID%^T3%ITEMNAME%^B4G%RANDOMID%^B4LE%RANDOMID%^R1",
+ "grab_all":"^T3^B4R^R1"
+ },
"nearby":{
"players_nearby":"Players Nearby:",
"east":"East:",
@@ -197,6 +206,7 @@
{"word":"shit","reason_type":"profanity","match_all":true},
{"word":"cunt","reason_type":"profanity","match_all":true},
{"word":"nigger","reason_type":"profanity","match_all":true},
+ {"word":"stfu","reason_type":"profanity","match_all":false},
{"word":"nigga","reason_type":"profanity","match_all":true},
{"word":"homo","reason_type":"profanity","match_all":false},
{"word":"homosexual","reason_type":"profanity","match_all":true},
diff --git a/Horse Isle Server/Horse Isle Server/Chat.cs b/Horse Isle Server/Horse Isle Server/Chat.cs
index 7808bdf..dbd5a80 100644
--- a/Horse Isle Server/Horse Isle Server/Chat.cs
+++ b/Horse Isle Server/Horse Isle Server/Chat.cs
@@ -331,12 +331,18 @@ namespace Horse_Isle_Server
if (user.Moderator || user.Administrator)
return Messages.FormatModChatMessage(user.Username, message);
else
- return user.Username+" is a hacker! (Sent in mod channel without being a mod) Maybe ban?";
+ {
+ Logger.HackerPrint(user.Username + " Tried to send in mod chat without being a moderator. (Hack/Code Attempt)");
+ return user.Username + " is a hacker! (Sent in mod channel without being a mod) Maybe ban?";
+ }
case ChatChannel.Admin:
if (user.Administrator)
return Messages.FormatAdminChatMessage(user.Username, message);
else
+ {
+ Logger.HackerPrint(user.Username + " Tried to send in mod chat without being a moderator. (Hack/Code Attempt)");
return user.Username + " is a hacker! (Sent in admin channel without being a admin) Maybe ban?";
+ }
default:
Logger.ErrorPrint(user.Username + " is trying to end a message in unknown channel " + channel.ToString("X"));
return "not implemented yet :(";
diff --git a/Horse Isle Server/Horse Isle Server/Client.cs b/Horse Isle Server/Horse Isle Server/Client.cs
index 969e781..cb74fe2 100644
--- a/Horse Isle Server/Horse Isle Server/Client.cs
+++ b/Horse Isle Server/Horse Isle Server/Client.cs
@@ -161,6 +161,9 @@ namespace Horse_Isle_Server
case PacketBuilder.PACKET_INVENTORY:
Server.OnInventoryRequested(this, Packet);
break;
+ case PacketBuilder.PACKET_ITEM_INTERACTION:
+ Server.OnItemInteraction(this,Packet);
+ break;
default:
Logger.ErrorPrint("Unimplemented Packet: " + BitConverter.ToString(Packet).Replace('-', ' '));
break;
diff --git a/Horse Isle Server/Horse Isle Server/Database.cs b/Horse Isle Server/Horse Isle Server/Database.cs
index adf3b7f..82a971d 100644
--- a/Horse Isle Server/Horse Isle Server/Database.cs
+++ b/Horse Isle Server/Horse Isle Server/Database.cs
@@ -19,7 +19,8 @@ namespace Horse_Isle_Server
string MailTable = "CREATE TABLE Mailbox(IdTo INT, PlayerFrom TEXT(16),Subject TEXT(128), Message Text(1028), TimeSent INT)";
string BuddyTable = "CREATE TABLE BuddyList(Id INT, IdFriend INT, Pending BOOL)";
string WorldTable = "CREATE TABLE World(Time INT,Day INT, Year INT, Weather TEXT(64))";
- string DroppedTable = "CREATE TABLE DroppedItems(X INT, Y INT, ItemID INT)";
+ string InventoryTable = "CREATE TABLE Inventory(PlayerID INT, RandomID INT, ItemID INT)";
+ string DroppedItems = "CREATE TABLE DroppedItems(X INT, Y INT, RandomID INT, ItemID INT, DespawnTimer INT)";
try
{
@@ -72,11 +73,25 @@ namespace Horse_Isle_Server
Logger.WarnPrint(e.Message);
};
+
try
{
MySqlCommand sqlCommand = db.CreateCommand();
- sqlCommand.CommandText = DroppedTable;
+ sqlCommand.CommandText = DroppedItems;
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ catch (Exception e)
+ {
+ Logger.WarnPrint(e.Message);
+ };
+
+ try
+ {
+
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = InventoryTable;
sqlCommand.ExecuteNonQuery();
sqlCommand.Dispose();
}
@@ -229,6 +244,129 @@ namespace Horse_Isle_Server
}
}
+ public static List GetPlayerInventory(int playerId)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+
+ sqlCommand.CommandText = "SELECT ItemId,RandomId FROM Inventory WHERE PlayerId=@playerId";
+ sqlCommand.Parameters.AddWithValue("@playerId", playerId);
+ sqlCommand.Prepare();
+ MySqlDataReader reader = sqlCommand.ExecuteReader();
+ List instances = new List();
+
+ while(reader.Read())
+ {
+ instances.Add(new ItemInstance(reader.GetInt32(0), reader.GetInt32(1)));
+ }
+ sqlCommand.Dispose();
+ return instances;
+ }
+ }
+ public static void AddItemToInventory(int playerId, ItemInstance instance)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+
+ sqlCommand.CommandText = "INSERT INTO Inventory VALUES(@playerId,@randomId,@itemId)";
+ sqlCommand.Parameters.AddWithValue("@playerId", playerId);
+ sqlCommand.Parameters.AddWithValue("@randomId", instance.RandomID);
+ sqlCommand.Parameters.AddWithValue("@itemId", instance.ItemID);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+
+ public static void RemoveItemFromInventory(int playerId, ItemInstance instance)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+
+ sqlCommand.CommandText = "DELETE FROM Inventory WHERE (PlayerId=@id AND RandomId=@randomId)";
+ sqlCommand.Parameters.AddWithValue("@playerId", playerId);
+ sqlCommand.Parameters.AddWithValue("@randomId", instance.RandomID);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+
+ public static void RemoveDroppedItem(int randomId)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+
+ sqlCommand.CommandText = "DELETE FROM Inventory WHERE (RandomId=@randomId)";
+ sqlCommand.Parameters.AddWithValue("@randomId", randomId);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+ }
+ }
+
+ public static DroppedItems.DroppedItem[] GetDroppedItems()
+ {
+ List itemList = new List();
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.CommandText = "SELECT * FROM DroppedItems";
+ sqlCommand.Prepare();
+ MySqlDataReader reader = sqlCommand.ExecuteReader();
+ while(reader.Read())
+ {
+ DroppedItems.DroppedItem droppedItem = new DroppedItems.DroppedItem();
+ droppedItem.X = reader.GetInt32(0);
+ droppedItem.Y = reader.GetInt32(1);
+ droppedItem.DespawnTimer = reader.GetInt32(4);
+ ItemInstance instance = new ItemInstance(reader.GetInt32(3),reader.GetInt32(4));
+ droppedItem.instance = instance;
+ itemList.Add(droppedItem);
+ }
+ sqlCommand.Dispose();
+
+ }
+ return itemList.ToArray();
+ }
+ public static void AddDroppedItems(DroppedItems.DroppedItem[] items)
+ {
+ using (MySqlConnection db = new MySqlConnection(ConnectionString))
+ {
+ db.Open();
+ MySqlTransaction transaction = db.BeginTransaction();
+
+
+ foreach (DroppedItems.DroppedItem item in items)
+ {
+
+ MySqlCommand sqlCommand = db.CreateCommand();
+ sqlCommand.Transaction = transaction;
+ sqlCommand.CommandText = "INSERT INTO DroppedItems VALUES(@x, @y, @randomId, @itemId, @despawnTimer)";
+ sqlCommand.Parameters.AddWithValue("@x", item.X);
+ sqlCommand.Parameters.AddWithValue("@y", item.Y);
+ sqlCommand.Parameters.AddWithValue("@randomId", item.instance.RandomID);
+ sqlCommand.Parameters.AddWithValue("@itemId", item.instance.ItemID);
+ sqlCommand.Parameters.AddWithValue("@despawnTimer", item.DespawnTimer);
+ sqlCommand.Prepare();
+ sqlCommand.ExecuteNonQuery();
+ sqlCommand.Dispose();
+
+ }
+
+ transaction.Commit();
+ }
+
+ }
public static void AddMail(int toId, string fromName, string subject, string message)
{
using (MySqlConnection db = new MySqlConnection(ConnectionString))
diff --git a/Horse Isle Server/Horse Isle Server/DroppedItems.cs b/Horse Isle Server/Horse Isle Server/DroppedItems.cs
new file mode 100644
index 0000000..76423e9
--- /dev/null
+++ b/Horse Isle Server/Horse Isle Server/DroppedItems.cs
@@ -0,0 +1,190 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Horse_Isle_Server
+{
+ class DroppedItems
+ {
+ public struct DroppedItem
+ {
+ public int X;
+ public int Y;
+ public int DespawnTimer;
+ public ItemInstance instance;
+ }
+ private static int epoch = 0;
+ private static List droppedItemsList = new List();
+ public static int GetCountOfItem(Item.ItemInformation item)
+ {
+
+ DroppedItem[] dropedItems = droppedItemsList.ToArray();
+ int count = 0;
+ foreach(DroppedItem droppedItem in dropedItems)
+ {
+ if(droppedItem.instance.ItemID == item.Id)
+ {
+ count++;
+ }
+ }
+ return count;
+ }
+
+ public static DroppedItem[] GetItemsAt(int x, int y)
+ {
+
+ DroppedItem[] dropedItems = droppedItemsList.ToArray();
+ List items = new List();
+ foreach(DroppedItem droppedItem in dropedItems)
+ {
+ if(droppedItem.X == x && droppedItem.Y == y)
+ {
+ items.Add(droppedItem);
+ }
+ }
+ return items.ToArray();
+ }
+ public static void ReadFromDatabase()
+ {
+ DroppedItem[] items = Database.GetDroppedItems();
+ foreach (DroppedItem droppedItem in items)
+ droppedItemsList.Add(droppedItem);
+ }
+ public static void Update()
+ {
+ int epoch_new = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
+
+ DespawnItems(epoch, epoch_new);
+ epoch = epoch_new;
+
+ GenerateItems();
+ }
+ public static void RemoveDroppedItem(DroppedItem item)
+ {
+ Database.RemoveDroppedItem(item.instance.RandomID);
+ droppedItemsList.Remove(item);
+ }
+ public static DroppedItem GetDroppedItemById(int randomId)
+ {
+
+ DroppedItem[] dropedItems = droppedItemsList.ToArray();
+
+ foreach (DroppedItem item in dropedItems)
+ {
+ if(item.instance.RandomID == randomId)
+ {
+ return item;
+ }
+ }
+
+ throw new KeyNotFoundException("Random id: " + randomId.ToString() + " not found");
+
+ }
+ public static void DespawnItems(int old_epoch, int new_epoch)
+ {
+ DroppedItem[] items = droppedItemsList.ToArray();
+ foreach (DroppedItem item in items)
+ {
+ if(old_epoch + item.DespawnTimer < new_epoch)
+ {
+ if(Server.GetUsersAt(item.X, item.Y,true,true).Length == 0)
+ {
+ RemoveDroppedItem(item);
+ }
+ }
+ }
+ }
+ public static void GenerateItems()
+ {
+ int newItems = 0;
+ foreach (Item.ItemInformation item in Item.Items)
+ {
+ int count = GetCountOfItem(item);
+ while (count < item.SpawnParamaters.SpawnCap)
+ {
+
+ count++;
+
+ int despawnTimer = Server.RandomNumberGenerator.Next(900, 1500);
+
+ if (item.SpawnParamaters.SpawnInArea != null)
+ {
+
+ }
+ else if (item.SpawnParamaters.SpawnOnSpecialTile != null)
+ {
+
+ }
+ else if (item.SpawnParamaters.SpawnNearSpecialTile != null)
+ {
+
+ }
+ else if (item.SpawnParamaters.SpawnOnTileType != null)
+ {
+
+ while (true)
+ {
+ // Pick a random isle:
+ int isleId = Server.RandomNumberGenerator.Next(0, World.Isles.Count);
+ World.Isle isle = World.Isles[isleId];
+
+ // Pick a random location inside the isle
+ int tryX = Server.RandomNumberGenerator.Next(isle.StartX, isle.EndX);
+ int tryY = Server.RandomNumberGenerator.Next(isle.StartY, isle.EndY);
+
+
+ if (World.InTown(tryX, tryY) || World.InSpecialTile(tryX, tryY))
+ continue;
+
+ if (Map.CheckPassable(tryX, tryY)) // Can the player walk here?
+ {
+ int TileID = Map.GetTileId(tryX, tryY, false);
+ string TileType = Map.TerrainTiles[TileID - 1].Type; // Is it the right type?
+
+ if (item.SpawnParamaters.SpawnOnTileType == TileType)
+ {
+ ItemInstance instance = new ItemInstance(item.Id);
+ DroppedItem droppedItem = new DroppedItem();
+ droppedItem.X = tryX;
+ droppedItem.Y = tryY;
+ droppedItem.DespawnTimer = despawnTimer;
+ droppedItem.instance = instance;
+ droppedItemsList.Add(droppedItem);
+ Logger.DebugPrint("Created Item ID: " + instance.ItemID + " in " + isle.Name + " at: X: " + droppedItem.X + " Y: " + droppedItem.Y);
+ newItems++;
+ break;
+
+ }
+ else
+ {
+ continue;
+ }
+ }
+ else
+ {
+ continue;
+ }
+ }
+
+ }
+
+
+
+ }
+
+ }
+ if(newItems > 0)
+ Database.AddDroppedItems(droppedItemsList.ToArray());
+ }
+
+ public static void Init()
+ {
+ ReadFromDatabase();
+ Logger.InfoPrint("Generating items, (this may take awhile on a fresh database!)");
+ GenerateItems();
+ }
+
+ }
+}
diff --git a/Horse Isle Server/Horse Isle Server/Gamedata.cs b/Horse Isle Server/Horse Isle Server/Gamedata.cs
index f86c829..eb8c67f 100644
--- a/Horse Isle Server/Horse Isle Server/Gamedata.cs
+++ b/Horse Isle Server/Horse Isle Server/Gamedata.cs
@@ -154,7 +154,7 @@ namespace Horse_Isle_Server
Logger.DebugPrint("Registered Transport Location: "+ transportPlace.LocationTitle+" To Goto X: " + transportPlace.GotoX + " Y: " + transportPlace.GotoY);
}
-
+ // Register Items
int totalItems = gameData.item.item_list.Count;
for (int i = 0; i < totalItems; i++)
{
@@ -183,12 +183,12 @@ namespace Horse_Isle_Server
item.Effects = effectsList;
item.SpawnParamaters = new Item.SpawnRules();
item.SpawnParamaters.SpawnCap = gameData.item.item_list[i].spawn_parameters.spawn_cap;
- item.SpawnParamaters.SpawnInArea = gameData.item.item_list[i].spawn_in_area;
- item.SpawnParamaters.SpawnOnTileType = gameData.item.item_list[i].spawn_on_tile_type;
- item.SpawnParamaters.SpawnOnSpecialTile = gameData.item.item_list[i].spawn_on_special_tile;
- item.SpawnParamaters.SpawnNearSpecialTile = gameData.item.item_list[i].spawn_near_special_tile;
+ item.SpawnParamaters.SpawnInArea = gameData.item.item_list[i].spawn_parameters.spawn_in_area;
+ item.SpawnParamaters.SpawnOnTileType = gameData.item.item_list[i].spawn_parameters.spawn_on_tile_type;
+ item.SpawnParamaters.SpawnOnSpecialTile = gameData.item.item_list[i].spawn_parameters.spawn_on_special_tile;
+ item.SpawnParamaters.SpawnNearSpecialTile = gameData.item.item_list[i].spawn_parameters.spawn_near_special_tile;
- Logger.DebugPrint("Registered Item ID: " + item.Id + " Name: " + item.Name);
+ Logger.DebugPrint("Registered Item ID: " + item.Id + " Name: " + item.Name + " spawns on: "+item.SpawnParamaters.SpawnOnTileType);
Item.Items.Add(item);
}
@@ -247,11 +247,17 @@ namespace Horse_Isle_Server
Messages.TileFormat = gameData.messages.meta.tile_format;
Messages.TransportFormat = gameData.messages.meta.transport_format;
Messages.InventoryFormat = gameData.messages.meta.inventory_format;
- Messages.NothingMessage = gameData.messages.meta.nothing_message;
Messages.ExitThisPlace = gameData.messages.meta.exit_this_place;
Messages.BackToMap = gameData.messages.meta.back_to_map;
+ Messages.LongFullLine = gameData.messages.meta.long_full_line;
Messages.MetaTerminator = gameData.messages.meta.end_of_meta;
+ Messages.NothingMessage = gameData.messages.meta.dropped_items.nothing_message;
+ Messages.ItemsOnGroundMessage = gameData.messages.meta.dropped_items.items_message;
+ Messages.GrabItemFormat = gameData.messages.meta.dropped_items.item_format;
+ Messages.GrabbedItemMessage = gameData.messages.grab_message;
+ Messages.GrabAllItemsMessage = gameData.messages.grab_all_message;
+
Messages.NearbyPlayers = gameData.messages.meta.nearby.players_nearby;
Messages.North = gameData.messages.meta.nearby.north;
Messages.East = gameData.messages.meta.nearby.east;
@@ -268,7 +274,8 @@ namespace Horse_Isle_Server
{
Map.TerrainTile tile = new Map.TerrainTile();
tile.Passable = gameData.tile_paramaters.terrain_tiles[i].passable;
- tile.Type = gameData.tile_paramaters.terrain_tiles[i].passable;
+ tile.Type = gameData.tile_paramaters.terrain_tiles[i].tile_type;
+ Logger.DebugPrint("Registered Tile: " + i + " Passable: " + tile.Passable + " Type: " + tile.Type);
terrainTiles.Add(tile);
}
Map.TerrainTiles = terrainTiles.ToArray();
@@ -286,7 +293,7 @@ namespace Horse_Isle_Server
// Inventory
- Inventory.DefaultInventoryMax = gameData.item.max_carryable;
+ Messages.DefaultInventoryMax = gameData.item.max_carryable;
// Swf
Messages.WagonCutscene = gameData.transport.wagon_cutscene;
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 480d351..9886002 100644
--- a/Horse Isle Server/Horse Isle Server/Horse Isle Server.csproj
+++ b/Horse Isle Server/Horse Isle Server/Horse Isle Server.csproj
@@ -79,7 +79,9 @@
-
+
+
+
@@ -89,6 +91,7 @@
+
diff --git a/Horse Isle Server/Horse Isle Server/IInventory.cs b/Horse Isle Server/Horse Isle Server/IInventory.cs
new file mode 100644
index 0000000..a607ef7
--- /dev/null
+++ b/Horse Isle Server/Horse Isle Server/IInventory.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Horse_Isle_Server
+{
+ interface IInventory
+ {
+
+ void Add(ItemInstance item);
+ void Remove(ItemInstance item);
+
+ int Count
+ {
+ get;
+ }
+
+ ItemInstance[] GetItemList();
+
+
+ }
+}
diff --git a/Horse Isle Server/Horse Isle Server/Item.cs b/Horse Isle Server/Horse Isle Server/Item.cs
index b93a1c9..c1084a4 100644
--- a/Horse Isle Server/Horse Isle Server/Item.cs
+++ b/Horse Isle Server/Horse Isle Server/Item.cs
@@ -44,5 +44,17 @@ namespace Horse_Isle_Server
}
public static List Items = new List();
+
+ public static ItemInformation GetItemById(int id)
+ {
+ foreach(ItemInformation item in Items)
+ {
+ if(item.Id == id)
+ {
+ return item;
+ }
+ }
+ throw new KeyNotFoundException("Item id " + id + " Not found!");
+ }
}
}
diff --git a/Horse Isle Server/Horse Isle Server/ItemInstance.cs b/Horse Isle Server/Horse Isle Server/ItemInstance.cs
new file mode 100644
index 0000000..85d3ee4
--- /dev/null
+++ b/Horse Isle Server/Horse Isle Server/ItemInstance.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Horse_Isle_Server
+{
+ class ItemInstance
+ {
+ public int RandomID;
+ public int ItemID;
+ private static int prevId = 0;
+
+
+ public Item.ItemInformation GetItemInfo()
+ {
+ return Item.GetItemById(ItemID);
+
+ }
+
+ public ItemInstance(int id,int randomId = -1)
+ {
+ prevId++;
+ if (randomId == -1)
+ RandomID = prevId;
+ else
+ RandomID = randomId;
+
+ if (RandomID > prevId)
+ prevId = RandomID + 1;
+
+ ItemID = id;
+
+ }
+
+ }
+}
diff --git a/Horse Isle Server/Horse Isle Server/Logger.cs b/Horse Isle Server/Horse Isle Server/Logger.cs
index 531b867..7354450 100644
--- a/Horse Isle Server/Horse Isle Server/Logger.cs
+++ b/Horse Isle Server/Horse Isle Server/Logger.cs
@@ -8,6 +8,10 @@ namespace Horse_Isle_Server
{
class Logger
{
+ public static void HackerPrint(string text) // When someone is obviously cheating.
+ {
+ Console.WriteLine("[HACK] " + text);
+ }
public static void DebugPrint(string text)
{
if (ConfigReader.Debug)
@@ -17,7 +21,7 @@ namespace Horse_Isle_Server
{
Console.WriteLine("[WARN] " + text);
}
- public static void ErrorPrint(string text)
+ public static void ErrorPrint(string text)
{
Console.WriteLine("[ERROR] " + text);
}
diff --git a/Horse Isle Server/Horse Isle Server/Map.cs b/Horse Isle Server/Horse Isle Server/Map.cs
index a8c31a2..5a2045a 100644
--- a/Horse Isle Server/Horse Isle Server/Map.cs
+++ b/Horse Isle Server/Horse Isle Server/Map.cs
@@ -67,11 +67,11 @@ namespace Horse_Isle_Server
bool tilePassable = false;
if (terrainPassable || overlayPassable)
tilePassable = true;
- if (!overlayPassable && otileId != 0)
+ if (!overlayPassable && (tileId != 0 && otileId != 0))
tilePassable = false;
- Logger.DebugPrint("Checking tile passibility for tileid: " + tileId + " and overlay tileid " + otileId + " at " + x + "," + y);
+
return tilePassable;
}
diff --git a/Horse Isle Server/Horse Isle Server/Messages.cs b/Horse Isle Server/Horse Isle Server/Messages.cs
index 480e188..9a71612 100644
--- a/Horse Isle Server/Horse Isle Server/Messages.cs
+++ b/Horse Isle Server/Horse Isle Server/Messages.cs
@@ -8,6 +8,9 @@ namespace Horse_Isle_Server
{
class Messages
{
+ public static int RequiredChatViolations;
+ public static int DefaultInventoryMax;
+
// Announcements
public static string NewUserMessage;
public static string WelcomeFormat;
@@ -41,11 +44,19 @@ namespace Horse_Isle_Server
public static string AdminChatFormatForSender;
public static string ModChatFormatForSender;
- public static int RequiredChatViolations;
public static string ChatViolationMessageFormat;
public static string PasswordNotice;
public static string CapsNotice;
+ //Dropped Items
+
+ public static string NothingMessage;
+ public static string ItemsOnGroundMessage;
+ public static string GrabItemFormat;
+ public static string GrabAllItemsMessage;
+ public static string GrabbedItemMessage;
+ public static string GrabbedAllObjectsMessage;
+
// Meta
public static string IsleFormat;
public static string TownFormat;
@@ -60,12 +71,12 @@ namespace Horse_Isle_Server
public static string West;
public static string TileFormat;
- public static string NothingMessage;
public static string Seperator;
public static string InventoryFormat;
public static string ExitThisPlace;
public static string BackToMap;
+ public static string LongFullLine;
public static string MetaTerminator;
// Disconnect Messages
@@ -82,11 +93,15 @@ namespace Horse_Isle_Server
return ChatViolationMessageFormat.Replace("%AMOUNT%", RequiredChatViolations.ToString()).Replace("%REASON%", violationReason.Message);
}
- public static string FormatInventoryMeta(int itemCount, int maxItems)
+ public static string FormatPlayerInventoryHeaderMeta(int itemCount, int maxItems)
{
return InventoryFormat.Replace("%ITEMCOUNT%", itemCount.ToString()).Replace("%MAXITEMS%", maxItems.ToString());
}
// Meta
+ public static string FormatGrabItemMessage(string name, int randomid, int iconid)
+ {
+ return GrabItemFormat.Replace("%ICONID%",iconid.ToString()).Replace("%ITEMNAME%", name).Replace("%RANDOMID%", randomid.ToString());
+ }
public static string FormatTransportMessage(string method, string place, int cost, int id, int x, int y)
{
string xy = "";
diff --git a/Horse Isle Server/Horse Isle Server/Meta.cs b/Horse Isle Server/Horse Isle Server/Meta.cs
index 85a20d2..30f26ed 100644
--- a/Horse Isle Server/Horse Isle Server/Meta.cs
+++ b/Horse Isle Server/Horse Isle Server/Meta.cs
@@ -81,12 +81,22 @@ namespace Horse_Isle_Server
string message = "";
message += Messages.Seperator + buildNearbyString(x, y);
+
// Dropped Items
- int[] itemIds = World.GetDroppedItems(x, y);
- if (itemIds.Length == 0)
+ DroppedItems.DroppedItem[] Items = DroppedItems.GetItemsAt(x, y);
+ if (Items.Length == 0)
message += Messages.NothingMessage;
-
-
+ else
+ {
+ message += Messages.ItemsOnGroundMessage;
+ foreach(DroppedItems.DroppedItem item in Items)
+ {
+ Item.ItemInformation itemInfo = item.instance.GetItemInfo();
+ message += Messages.FormatGrabItemMessage(itemInfo.Name, item.instance.RandomID, itemInfo.IconId);
+ }
+ message += Messages.GrabAllItemsMessage;
+ }
+ Logger.DebugPrint(message);
return message;
}
public static string BuildTransportInfo(Transport.TransportPoint transportPoint)
@@ -126,11 +136,10 @@ namespace Horse_Isle_Server
return message;
}
- public static string BuildInventoryInfo(Inventory inv)
+ public static string BuildInventoryInfo(IInventory inv)
{
string message = "";
- message += Messages.FormatInventoryMeta(inv.ItemList.Count, inv.MaxItems);
-
+ message += Messages.FormatPlayerInventoryHeaderMeta(inv.Count, Messages.DefaultInventoryMax);
return message;
}
public static string BuildMetaInfo(int x, int y)
diff --git a/Horse Isle Server/Horse Isle Server/PacketBuilder.cs b/Horse Isle Server/Horse Isle Server/PacketBuilder.cs
index 7714e74..f5f25d5 100644
--- a/Horse Isle Server/Horse Isle Server/PacketBuilder.cs
+++ b/Horse Isle Server/Horse Isle Server/PacketBuilder.cs
@@ -21,6 +21,7 @@ namespace Horse_Isle_Server
public const byte PACKET_SWF_MODULE_GENTLE = 0x2A;
public const byte PACKET_PLACE_INFO = 0x1E;
public const byte PACKET_AREA_DEFS = 0x79;
+ public const byte PACKET_ITEM_INTERACTION = 0x1E;
public const byte PACKET_ANNOUNCEMENT = 0x7E;
public const byte PACKET_TILE_FLAGS = 0x75;
public const byte PACKET_PLAYSOUND = 0x23;
@@ -32,10 +33,12 @@ namespace Horse_Isle_Server
public const byte PACKET_LEAVE = 0x7D;
public const byte PACKET_PLAYERINFO = 0x16;
+
+ public const byte PICKUP_OBJECT = 0x14;
public const byte PLAYERINFO_LEAVE = 0x16;
public const byte PLAYERINFO_UPDATE_OR_CREATE = 0x15;
-
+
public const byte VIEW_PROFILE = 0x14;
public const byte SAVE_PROFILE = 0x15;
diff --git a/Horse Isle Server/Horse Isle Server/PlayerInventory.cs b/Horse Isle Server/Horse Isle Server/PlayerInventory.cs
new file mode 100644
index 0000000..c59ec2d
--- /dev/null
+++ b/Horse Isle Server/Horse Isle Server/PlayerInventory.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Horse_Isle_Server
+{
+ class PlayerInventory : IInventory
+ {
+ private User baseUser;
+ private List instances = new List();
+
+ public PlayerInventory(User forUser)
+ {
+ baseUser = forUser;
+ instances = Database.GetPlayerInventory(baseUser.Id);
+ }
+
+ public int Count
+ {
+ get
+ {
+ return instances.Count;
+ }
+ }
+
+ public void Add(ItemInstance item)
+ {
+ instances.Add(item);
+ Database.AddItemToInventory(baseUser.Id, item);
+ }
+
+ public ItemInstance[] GetItemList()
+ {
+ return instances.ToArray();
+ }
+
+ public void Remove(ItemInstance item)
+ {
+ instances.Remove(item);
+ Database.RemoveItemFromInventory(baseUser.Id, item);
+ }
+ }
+}
diff --git a/Horse Isle Server/Horse Isle Server/Program.cs b/Horse Isle Server/Horse Isle Server/Program.cs
index 9cb0862..dd3953a 100644
--- a/Horse Isle Server/Horse Isle Server/Program.cs
+++ b/Horse Isle Server/Horse Isle Server/Program.cs
@@ -18,6 +18,7 @@ namespace Horse_Isle_Server
Map.OpenMap();
Gamedata.ReadGamedata();
World.ReadWorldData();
+ DroppedItems.Init();
Server.StartServer();
}
diff --git a/Horse Isle Server/Horse Isle Server/Server.cs b/Horse Isle Server/Horse Isle Server/Server.cs
index 24be539..5003e54 100644
--- a/Horse Isle Server/Horse Isle Server/Server.cs
+++ b/Horse Isle Server/Horse Isle Server/Server.cs
@@ -14,7 +14,7 @@ namespace Horse_Isle_Server
{
public static Socket ServerSocket;
-
+ private static Timer serverTimer;
public static Client[] ConnectedClients // Done to prevent Enumerator Changed errors.
{
@@ -26,12 +26,11 @@ namespace Horse_Isle_Server
public static int IdleTimeout;
public static int IdleWarning;
-
+ public static Random RandomNumberGenerator = new Random();
// used for world time,
private static int gameTickSpeed = 4320; // Changing this to ANYTHING else will cause desync with the client.
- private static Timer serverTimer;
-
+
private static List connectedClients = new List();
public static void OnCrossdomainPolicyRequest(Client sender) // When a cross-domain-policy request is received.
{
@@ -326,27 +325,43 @@ namespace Horse_Isle_Server
Logger.ErrorPrint(sender.RemoteIp + " Tried to use a transport with id that is NaN.");
return;
}
-
- Transport.TransportLocation transportLocation = Transport.GetTransportLocation(transportid);
- if (sender.LoggedinUser.Money >= transportLocation.Cost)
+ try
{
-
- string swfToLoad = Messages.BoatCutscene;
- if (transportLocation.Type == "WAGON")
- swfToLoad = Messages.WagonCutscene;
-
- if (transportLocation.Type != "ROWBOAT")
+ Transport.TransportPoint transportPoint = Transport.GetTransportPoint(sender.LoggedinUser.X, sender.LoggedinUser.Y);
+ if (transportPoint.X != sender.LoggedinUser.X && transportPoint.Y != sender.LoggedinUser.Y)
{
- byte[] swfModulePacket = PacketBuilder.CreateSwfModulePacket(swfToLoad, PacketBuilder.PACKET_SWF_CUTSCENE);
- sender.SendPacket(swfModulePacket);
+ Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to use transport id: " + transportid.ToString() + " while not the correct transport point!");
+ return;
}
- Teleport(sender, transportLocation.GotoX, transportLocation.GotoY);
+ Transport.TransportLocation transportLocation = Transport.GetTransportLocation(transportid);
- sender.LoggedinUser.Money -= transportLocation.Cost;
-
+
+ if (sender.LoggedinUser.Money >= transportLocation.Cost)
+ {
+
+
+ string swfToLoad = Messages.BoatCutscene;
+ if (transportLocation.Type == "WAGON")
+ swfToLoad = Messages.WagonCutscene;
+
+ if (transportLocation.Type != "ROWBOAT")
+ {
+ byte[] swfModulePacket = PacketBuilder.CreateSwfModulePacket(swfToLoad, PacketBuilder.PACKET_SWF_CUTSCENE);
+ sender.SendPacket(swfModulePacket);
+ }
+
+ Teleport(sender, transportLocation.GotoX, transportLocation.GotoY);
+
+ sender.LoggedinUser.Money -= transportLocation.Cost;
+ }
}
-
+ catch (KeyNotFoundException)
+ {
+ Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to use transport id: " + transportid.ToString() + " while not on a transport point!");
+ }
+
+
}
public static void OnChatPacket(Client sender, byte[] packet)
{
@@ -424,6 +439,59 @@ namespace Horse_Isle_Server
sender.SendPacket(chatPacketSender);
}
+ public static void OnItemInteraction(Client sender, byte[] packet)
+ {
+ if (!sender.LoggedIn)
+ {
+ Logger.ErrorPrint(sender.RemoteIp + " Sent object interaction packet when not logged in.");
+ return;
+ }
+ if (packet.Length < 3)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent an invalid object interaction packet.");
+ return;
+ }
+
+ byte action = packet[1];
+ switch(action)
+ {
+ case PacketBuilder.PICKUP_OBJECT:
+ string packetStr = Encoding.UTF8.GetString(packet);
+ string randomIdStr = packetStr.Substring(2, packet.Length - 2);
+ int randomId = 0;
+
+ try
+ {
+ randomId = Int32.Parse(randomIdStr);
+ }
+ catch(InvalidOperationException)
+ {
+ Logger.ErrorPrint(sender.LoggedinUser.Username + " Sent an invalid object interaction packet.");
+ return;
+ }
+
+ try
+ {
+ DroppedItems.DroppedItem item = DroppedItems.GetDroppedItemById(randomId);
+ sender.LoggedinUser.Inventory.Add(item.instance);
+ DroppedItems.RemoveDroppedItem(item);
+
+ UpdateAreaForAll(item.X, item.Y);
+
+ byte[] chatMessage = PacketBuilder.CreateChat(Messages.GrabbedItemMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
+ sender.SendPacket(chatMessage);
+ }
+ catch(KeyNotFoundException)
+ {
+ Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to grab a non existing object.");
+ return;
+ }
+
+ break;
+ }
+
+ }
+
public static void OnInventoryRequested(Client sender, byte[] packet)
{
if (!sender.LoggedIn)
@@ -434,11 +502,11 @@ namespace Horse_Isle_Server
if (packet.Length < 2)
{
- Logger.ErrorPrint(sender.RemoteIp + " Sent an invalid chat packet.");
+ Logger.ErrorPrint(sender.RemoteIp + " Sent an invalid inventory request packet.");
return;
}
- byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildInventoryInfo(sender.LoggedinUser.ItemInventory));
+ byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildInventoryInfo(sender.LoggedinUser.Inventory));
sender.SendPacket(metaPacket);
}
public static void OnLoginRequest(Client sender, byte[] packet)
@@ -678,7 +746,15 @@ namespace Horse_Isle_Server
}
-
+ public static void UpdateAreaForAll(int x, int y)
+ {
+ foreach(Client client in ConnectedClients)
+ {
+ if (client.LoggedIn)
+ if (client.LoggedinUser.X == x && client.LoggedinUser.Y == y)
+ UpdateArea(client, true);
+ }
+ }
public static void UpdateArea(Client forClient, bool justArea = false)
{
if (!forClient.LoggedIn)
@@ -756,6 +832,11 @@ namespace Horse_Isle_Server
private static void onTick(object state)
{
World.TickWorldClock();
+
+ if(World.ServerTime.Minutes % 20 == 0)
+ {
+ DroppedItems.Update();
+ }
}
public static void StartServer()
{
diff --git a/Horse Isle Server/Horse Isle Server/Transport.cs b/Horse Isle Server/Horse Isle Server/Transport.cs
index e227ce0..c636ed4 100644
--- a/Horse Isle Server/Horse Isle Server/Transport.cs
+++ b/Horse Isle Server/Horse Isle Server/Transport.cs
@@ -38,7 +38,7 @@ namespace Horse_Isle_Server
return transportPoint;
}
}
- throw new KeyNotFoundException("Cannot find transport port at x:" + x + "y:" + y);
+ throw new KeyNotFoundException("Cannot find transport point at x:" + x + "y:" + y);
}
public static TransportLocation GetTransportLocation(int id)
diff --git a/Horse Isle Server/Horse Isle Server/User.cs b/Horse Isle Server/Horse Isle Server/User.cs
index b43b30f..316a0e5 100644
--- a/Horse Isle Server/Horse Isle Server/User.cs
+++ b/Horse Isle Server/Horse Isle Server/User.cs
@@ -29,7 +29,7 @@ namespace Horse_Isle_Server
public Mailbox MailBox;
public Friends Friends;
public string Password; // For chat filter.
- public Inventory ItemInventory;
+ public PlayerInventory Inventory;
public int ChatViolations
{
get
@@ -162,8 +162,6 @@ namespace Horse_Isle_Server
NewPlayer = true;
}
- ItemInventory = new Inventory();
-
Id = UserId;
Username = Database.GetUsername(UserId);
@@ -197,6 +195,8 @@ namespace Horse_Isle_Server
Friends = new Friends(this);
LoggedinClient = baseClient;
+
+ Inventory = new PlayerInventory(this);
}
}
}
diff --git a/Horse Isle Server/Horse Isle Server/World.cs b/Horse Isle Server/Horse Isle Server/World.cs
index 4ddc143..7fd8c7b 100644
--- a/Horse Isle Server/Horse Isle Server/World.cs
+++ b/Horse Isle Server/Horse Isle Server/World.cs
@@ -197,10 +197,6 @@ namespace Horse_Isle_Server
throw new KeyNotFoundException("x,y not in a town!");
}
- public static int[] GetDroppedItems(int x, int y)
- {
- return new int[] { }; // Not implemented yet.
- }
public static string GetWeather()
{
return Database.GetWorldWeather();