teh big refactor

This commit is contained in:
SilicaAndPina 2020-10-31 14:18:54 +13:00
parent e3af85d511
commit 22b7d0fa27
36 changed files with 19658 additions and 21461 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,51 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server
{
class Action
{
public enum ActivationMethod
{
MANUAL,
SHOVEL,
BINOCULARS,
MAGNIFYING_GLASS,
RAKE
}
public struct AltActivation
{
public ActivationMethod Method;
public int ActivationX;
public int ActivationY;
}
public struct Requirements
{
public bool Track;
public int MaxCompletions;
public int MoneyRequired;
public int[] CompletedRequired;
public int[] NotCompletedRequired;
public int RequiredAward;
}
public struct GameAction
{
public int Id;
public string Notes;
public string AdventurousTitle;
public string Difficulty;
public string Author;
public int[] ActionIdRequired;
AltActivation Activation;
}
}
}

View file

@ -1,8 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using HISP.Player;
using HISP.Server;
namespace Horse_Isle_Server namespace HISP.Game
{ {
class Chat class Chat
{ {
@ -136,12 +138,12 @@ namespace Horse_Isle_Server
} }
} }
public static Client[] GetRecipiants(User user, ChatChannel channel, string to=null) public static GameClient[] GetRecipiants(User user, ChatChannel channel, string to=null)
{ {
if (channel == ChatChannel.All) if (channel == ChatChannel.All)
{ {
List<Client> recipiants = new List<Client>(); List<GameClient> recipiants = new List<GameClient>();
foreach (Client client in Server.ConnectedClients) foreach (GameClient client in GameServer.ConnectedClients)
{ {
if (client.LoggedIn) if (client.LoggedIn)
if (!client.LoggedinUser.MuteGlobal) if (!client.LoggedinUser.MuteGlobal)
@ -153,8 +155,8 @@ namespace Horse_Isle_Server
if(channel == ChatChannel.Ads) if(channel == ChatChannel.Ads)
{ {
List<Client> recipiants = new List<Client>(); List<GameClient> recipiants = new List<GameClient>();
foreach (Client client in Server.ConnectedClients) foreach (GameClient client in GameServer.ConnectedClients)
{ {
if (client.LoggedIn) if (client.LoggedIn)
if (!client.LoggedinUser.MuteAds) if (!client.LoggedinUser.MuteAds)
@ -166,8 +168,8 @@ namespace Horse_Isle_Server
if(channel == ChatChannel.Buddies) if(channel == ChatChannel.Buddies)
{ {
List<Client> recipiants = new List<Client>(); List<GameClient> recipiants = new List<GameClient>();
foreach (Client client in Server.ConnectedClients) foreach (GameClient client in GameServer.ConnectedClients)
{ {
if (client.LoggedIn) if (client.LoggedIn)
if (!client.LoggedinUser.MuteBuddy) if (!client.LoggedinUser.MuteBuddy)
@ -180,10 +182,10 @@ namespace Horse_Isle_Server
if (channel == ChatChannel.Isle) if (channel == ChatChannel.Isle)
{ {
List<Client> recipiants = new List<Client>(); List<GameClient> recipiants = new List<GameClient>();
if(World.InIsle(user.X,user.Y)) if(World.InIsle(user.X,user.Y))
{ {
User[] usersInSile = Server.GetUsersUsersInIsle(World.GetIsle(user.X, user.Y), true, false); User[] usersInSile = GameServer.GetUsersUsersInIsle(World.GetIsle(user.X, user.Y), true, false);
foreach (User userInIsle in usersInSile) foreach (User userInIsle in usersInSile)
{ {
if (user.Id != userInIsle.Id) if (user.Id != userInIsle.Id)
@ -193,15 +195,15 @@ namespace Horse_Isle_Server
} }
else else
{ {
return new Client[0]; return new GameClient[0];
} }
} }
if (channel == ChatChannel.Here) if (channel == ChatChannel.Here)
{ {
List<Client> recipiants = new List<Client>(); List<GameClient> recipiants = new List<GameClient>();
User[] usersHere = Server.GetUsersAt(user.X, user.Y, true, false); User[] usersHere = GameServer.GetUsersAt(user.X, user.Y, true, false);
foreach (User userHere in usersHere) foreach (User userHere in usersHere)
{ {
if (user.Id != userHere.Id) if (user.Id != userHere.Id)
@ -212,8 +214,8 @@ namespace Horse_Isle_Server
if (channel == ChatChannel.Near) if (channel == ChatChannel.Near)
{ {
List<Client> recipiants = new List<Client>(); List<GameClient> recipiants = new List<GameClient>();
User[] nearbyUsers = Server.GetNearbyUsers(user.X, user.Y, true, false); User[] nearbyUsers = GameServer.GetNearbyUsers(user.X, user.Y, true, false);
foreach (User nearbyUser in nearbyUsers) foreach (User nearbyUser in nearbyUsers)
{ {
if (user.Id != nearbyUser.Id) if (user.Id != nearbyUser.Id)
@ -227,11 +229,11 @@ namespace Horse_Isle_Server
if (!user.Moderator || !user.Administrator) // No mod chat for non-mods! if (!user.Moderator || !user.Administrator) // No mod chat for non-mods!
{ {
Logger.WarnPrint(user.Username + " attempted to send in MOD chat, without being a MOD."); Logger.WarnPrint(user.Username + " attempted to send in MOD chat, without being a MOD.");
return new Client[0]; return new GameClient[0];
} }
List<Client> recipiants = new List<Client>(); List<GameClient> recipiants = new List<GameClient>();
foreach (Client client in Server.ConnectedClients) foreach (GameClient client in GameServer.ConnectedClients)
{ {
if (client.LoggedIn) if (client.LoggedIn)
if (client.LoggedinUser.Moderator) if (client.LoggedinUser.Moderator)
@ -246,12 +248,12 @@ namespace Horse_Isle_Server
if (!user.Administrator) // No admin chat for non-admins! if (!user.Administrator) // No admin chat for non-admins!
{ {
Logger.WarnPrint(user.Username + " attempted to send in ADMIN chat, without being an ADMIN."); Logger.WarnPrint(user.Username + " attempted to send in ADMIN chat, without being an ADMIN.");
return new Client[0]; return new GameClient[0];
} }
List<Client> recipiants = new List<Client>(); List<GameClient> recipiants = new List<GameClient>();
foreach (Client client in Server.ConnectedClients) foreach (GameClient client in GameServer.ConnectedClients)
{ {
if (client.LoggedIn) if (client.LoggedIn)
if (client.LoggedinUser.Administrator) if (client.LoggedinUser.Administrator)
@ -265,8 +267,8 @@ namespace Horse_Isle_Server
{ {
if (to != null) if (to != null)
{ {
List<Client> recipiants = new List<Client>(); List<GameClient> recipiants = new List<GameClient>();
foreach (Client client in Server.ConnectedClients) foreach (GameClient client in GameServer.ConnectedClients)
{ {
if (client.LoggedIn) if (client.LoggedIn)
if (!client.LoggedinUser.MutePrivateMessage) if (!client.LoggedinUser.MutePrivateMessage)
@ -278,13 +280,13 @@ namespace Horse_Isle_Server
else else
{ {
Logger.ErrorPrint("Channel is " + channel + " (DM) BUT no 'to' Paramater was specfied"); Logger.ErrorPrint("Channel is " + channel + " (DM) BUT no 'to' Paramater was specfied");
return new Client[0]; return new GameClient[0];
} }
} }
Logger.ErrorPrint(user.Username + " Sent message in unknown channel: " + (byte)channel); Logger.ErrorPrint(user.Username + " Sent message in unknown channel: " + (byte)channel);
return new Client[0]; // No recipiants return new GameClient[0]; // No recipiants
} }
public static string DoCorrections(string message) public static string DoCorrections(string message)
@ -364,19 +366,19 @@ namespace Horse_Isle_Server
case ChatChannel.Isle: case ChatChannel.Isle:
int inIsle = 0; int inIsle = 0;
if (World.InIsle(user.X, user.Y)) if (World.InIsle(user.X, user.Y))
inIsle = Server.GetUsersUsersInIsle(World.GetIsle(user.X, user.Y), false, false).Length -1; inIsle = GameServer.GetUsersUsersInIsle(World.GetIsle(user.X, user.Y), false, false).Length -1;
return Messages.FormatIsleChatMessageForSender(inIsle, user.Username, message); return Messages.FormatIsleChatMessageForSender(inIsle, user.Username, message);
case ChatChannel.Here: case ChatChannel.Here:
int usersHere = Server.GetUsersAt(user.X, user.Y, false, false).Length -1; int usersHere = GameServer.GetUsersAt(user.X, user.Y, false, false).Length -1;
return Messages.FormatHereChatMessageForSender(usersHere, user.Username, message); return Messages.FormatHereChatMessageForSender(usersHere, user.Username, message);
case ChatChannel.Near: case ChatChannel.Near:
int nearbyUsers = Server.GetNearbyUsers(user.X, user.Y, false, false).Length -1; int nearbyUsers = GameServer.GetNearbyUsers(user.X, user.Y, false, false).Length -1;
return Messages.FormatNearChatMessageForSender(nearbyUsers, user.Username, message); return Messages.FormatNearChatMessageForSender(nearbyUsers, user.Username, message);
case ChatChannel.Mod: case ChatChannel.Mod:
int modsOnline = Server.GetNumberOfModsOnline() - 1; int modsOnline = GameServer.GetNumberOfModsOnline() - 1;
return Messages.FormatModChatForSender(modsOnline, user.Username, message); return Messages.FormatModChatForSender(modsOnline, user.Username, message);
case ChatChannel.Admin: case ChatChannel.Admin:
int adminsOnline = Server.GetNumberOfAdminsOnline() - 1; int adminsOnline = GameServer.GetNumberOfAdminsOnline() - 1;
return Messages.FormatAdminChatForSender(adminsOnline, user.Username, message); return Messages.FormatAdminChatForSender(adminsOnline, user.Username, message);
case ChatChannel.Dm: case ChatChannel.Dm:
return Messages.FormatDirectChatMessageForSender(user.Username, dmRecipiant, message); return Messages.FormatDirectChatMessageForSender(user.Username, dmRecipiant, message);

View file

@ -1,10 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using HISP.Server;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server namespace HISP.Game
{ {
class DroppedItems class DroppedItems
{ {
@ -98,7 +96,7 @@ namespace Horse_Isle_Server
{ {
if(new_epoch + item.DespawnTimer < old_epoch) if(new_epoch + item.DespawnTimer < old_epoch)
{ {
if(Server.GetUsersAt(item.X, item.Y,true,true).Length == 0) if(GameServer.GetUsersAt(item.X, item.Y,true,true).Length == 0)
{ {
RemoveDroppedItem(item); RemoveDroppedItem(item);
removedCount++; removedCount++;
@ -129,7 +127,7 @@ namespace Horse_Isle_Server
count++; count++;
int despawnTimer = Server.RandomNumberGenerator.Next(900, 1500); int despawnTimer = GameServer.RandomNumberGenerator.Next(900, 1500);
if (item.SpawnParamaters.SpawnInArea != null) if (item.SpawnParamaters.SpawnInArea != null)
{ {
@ -149,12 +147,12 @@ namespace Horse_Isle_Server
while (true) while (true)
{ {
// Pick a random isle: // Pick a random isle:
int isleId = Server.RandomNumberGenerator.Next(0, World.Isles.Count); int isleId = GameServer.RandomNumberGenerator.Next(0, World.Isles.Count);
World.Isle isle = World.Isles[isleId]; World.Isle isle = World.Isles[isleId];
// Pick a random location inside the isle // Pick a random location inside the isle
int tryX = Server.RandomNumberGenerator.Next(isle.StartX, isle.EndX); int tryX = GameServer.RandomNumberGenerator.Next(isle.StartX, isle.EndX);
int tryY = Server.RandomNumberGenerator.Next(isle.StartY, isle.EndY); int tryY = GameServer.RandomNumberGenerator.Next(isle.StartY, isle.EndY);
if (World.InTown(tryX, tryY) || World.InSpecialTile(tryX, tryY)) if (World.InTown(tryX, tryY) || World.InSpecialTile(tryX, tryY))

View file

@ -1,10 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server
namespace HISP.Game
{ {
class InventoryItem class InventoryItem
{ {

View file

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Horse_Isle_Server namespace HISP.Game
{ {
class Item class Item
{ {

View file

@ -1,10 +1,5 @@
using System; using HISP.Security;
using System.Collections.Generic; namespace HISP.Game
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server
{ {
class ItemInstance class ItemInstance
{ {

View file

@ -1,12 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO; using System.IO;
using System.Linq; using HISP.Server;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server namespace HISP.Game
{ {
class Map class Map
{ {

View file

@ -1,16 +1,18 @@
using System; using HISP.Server;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server namespace HISP.Game
{ {
class Messages class Messages
{ {
public static int RequiredChatViolations; public static int RequiredChatViolations;
public static int DefaultInventoryMax; public static int DefaultInventoryMax;
// Tools
public static string BinocularsNothing;
public static string MagnifyNothing;
public static string RakeNothing;
public static string ShovelNothing;
// Announcements // Announcements
public static string NewUserMessage; public static string NewUserMessage;
public static string WelcomeFormat; public static string WelcomeFormat;
@ -79,6 +81,8 @@ namespace Horse_Isle_Server
public static string NpcStartChatFormat; public static string NpcStartChatFormat;
public static string NpcChatpointFormat; public static string NpcChatpointFormat;
public static string NpcReplyFormat; public static string NpcReplyFormat;
public static string NpcInformationButton;
public static string NpcTalkButton;
// Meta // Meta
public static string IsleFormat; public static string IsleFormat;
@ -116,6 +120,16 @@ namespace Horse_Isle_Server
return NpcChatpointFormat.Replace("%NAME%", name).Replace("%DESCRIPTION%", shortDescription).Replace("%TEXT%", chatText); return NpcChatpointFormat.Replace("%NAME%", name).Replace("%DESCRIPTION%", shortDescription).Replace("%TEXT%", chatText);
} }
public static string FormatNpcTalkButton(int npcId)
{
return NpcTalkButton.Replace("%ID%", npcId.ToString());
}
public static string FormatNpcInformationButton(int npcId)
{
return NpcInformationButton.Replace("%ID%", npcId.ToString());
}
public static string FormatNpcReply(string replyText, int replyId) public static string FormatNpcReply(string replyText, int replyId)
{ {
return NpcReplyFormat.Replace("%TEXT%", replyText).Replace("%ID%", replyId.ToString()); return NpcReplyFormat.Replace("%TEXT%", replyText).Replace("%ID%", replyId.ToString());
@ -279,7 +293,7 @@ namespace Horse_Isle_Server
} }
public static string FormatIdleWarningMessage() public static string FormatIdleWarningMessage()
{ {
return IdleWarningFormat.Replace("%WARN%", Server.IdleWarning.ToString()).Replace("%KICK%", Server.IdleTimeout.ToString()); return IdleWarningFormat.Replace("%WARN%", GameServer.IdleWarning.ToString()).Replace("%KICK%", GameServer.IdleTimeout.ToString());
} }
public static string FormatLoginMessage(string username) public static string FormatLoginMessage(string username)
@ -310,7 +324,7 @@ namespace Horse_Isle_Server
// Disconnect // Disconnect
public static string FormatIdleKickMessage() public static string FormatIdleKickMessage()
{ {
return IdleKickMessageFormat.Replace("%KICK%", Server.IdleTimeout.ToString()); return IdleKickMessageFormat.Replace("%KICK%", GameServer.IdleTimeout.ToString());
} }
} }

View file

@ -1,10 +1,7 @@
using System; using HISP.Player;
using System.Collections.Generic; using HISP.Server;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server namespace HISP.Game
{ {
class Meta class Meta
{ {
@ -30,7 +27,7 @@ namespace Horse_Isle_Server
{ {
string playersNearby = ""; string playersNearby = "";
User[] nearbyUsers = Server.GetNearbyUsers(x, y, true, true); User[] nearbyUsers = GameServer.GetNearbyUsers(x, y, true, true);
if (nearbyUsers.Length > 1) if (nearbyUsers.Length > 1)
{ {
playersNearby += Messages.NearbyPlayers; playersNearby += Messages.NearbyPlayers;
@ -99,18 +96,49 @@ namespace Horse_Isle_Server
} }
return message; return message;
} }
public static string buildNpc(User user, int x, int y)
{
string message = "";
Npc.NpcEntry[] entries = Npc.GetNpcByXAndY(x, y);
if (entries.Length > 0)
message += Messages.Seperator;
foreach (Npc.NpcEntry ent in entries)
{
if (ent.AdminOnly && !user.Administrator)
continue;
if (ent.RequiresQuestIdCompleted != 0)
if (user.Quests.GetTrackedQuestAmount(ent.RequiresQuestIdNotCompleted) <= 0)
continue;
if (ent.RequiresQuestIdNotCompleted != 0)
if (user.Quests.GetTrackedQuestAmount(ent.RequiresQuestIdCompleted) >= 1)
continue;
message += Messages.FormatNpcStartChatMessage(ent.IconId, ent.Name, ent.ShortDescription, ent.Id);
if (ent.LongDescription != "")
message += Messages.FormatNpcInformationButton(ent.Id);
message += Messages.FormatNpcTalkButton(ent.Id);
message += "^R1";
}
return message;
}
public static string BuildTransportInfo(Transport.TransportPoint transportPoint) public static string BuildTransportInfo(Transport.TransportPoint transportPoint)
{ {
string message = ""; string message = "";
// Build list of locations // Build list of locations
foreach(int transportLocationId in transportPoint.Locations) for (int i = 0; i < transportPoint.Locations.Length; i++)
{ {
int transportLocationId = transportPoint.Locations[i];
Transport.TransportLocation transportLocation = Transport.GetTransportLocation(transportLocationId); Transport.TransportLocation transportLocation = Transport.GetTransportLocation(transportLocationId);
message += Messages.FormatTransportMessage(transportLocation.Type, transportLocation.LocationTitle, transportLocation.Cost, transportLocation.Id, transportLocation.GotoX, transportLocation.GotoY); message += Messages.FormatTransportMessage(transportLocation.Type, transportLocation.LocationTitle, transportLocation.Cost, transportLocation.Id, transportLocation.GotoX, transportLocation.GotoY);
if(i + 1 != transportPoint.Locations.Length)
message += "^R1";
} }
return message; return message;
} }
public static string BuildSpecialTileInfo(World.SpecialTile specialTile) public static string BuildSpecialTileInfo(User user, World.SpecialTile specialTile)
{ {
string message = ""; string message = "";
@ -124,11 +152,7 @@ namespace Horse_Isle_Server
if (specialTile.Description != null && specialTile.Description != "") if (specialTile.Description != null && specialTile.Description != "")
message += specialTile.Description; message += specialTile.Description;
Npc.NpcEntry[] entries = Npc.GetNpcByXAndY(specialTile.X, specialTile.Y); message += buildNpc(user, specialTile.X, specialTile.Y);
if(entries.Length > 0)
message += Messages.Seperator;
foreach(Npc.NpcEntry ent in entries)
message += Messages.FormatNpcStartChatMessage(ent.IconId, ent.Name, ent.ShortDescription, ent.Id);
if (specialTile.Code == null) if (specialTile.Code == null)
message += buildCommonInfo(specialTile.X, specialTile.Y); message += buildCommonInfo(specialTile.X, specialTile.Y);
@ -184,29 +208,56 @@ namespace Horse_Isle_Server
message += Messages.MetaTerminator; message += Messages.MetaTerminator;
return message; return message;
} }
public static string BuildChatpoint(Npc.NpcEntry npc, Npc.NpcChat chatpoint) public static string BuildChatpoint(User user, Npc.NpcEntry npc, Npc.NpcChat chatpoint)
{ {
bool hideReplys = false;
if (chatpoint.ActivateQuestId != 0)
{
Quest.QuestEntry quest = Quest.GetQuestById(chatpoint.ActivateQuestId);
if (Quest.ActivateQuest(user, quest, true))
{
if(quest.GotoNpcChatpoint != -1)
chatpoint = Npc.GetNpcChatpoint(npc,quest.GotoNpcChatpoint);
if (quest.SuccessNpcChat != null)
chatpoint.ChatText = quest.SuccessNpcChat;
}
else
{
if (quest.GotoNpcChatpoint != -1)
chatpoint = Npc.GetNpcChatpoint(npc, quest.GotoNpcChatpoint);
if (quest.FailNpcChat != null)
chatpoint.ChatText = quest.FailNpcChat;
if (quest.HideReplyOnFail)
hideReplys = true;
}
}
string message = ""; string message = "";
message += Messages.FormatNpcChatpoint(npc.Name, npc.ShortDescription, chatpoint.ChatText); message += Messages.FormatNpcChatpoint(npc.Name, npc.ShortDescription, chatpoint.ChatText);
foreach(Npc.NpcReply reply in chatpoint.Replies) foreach(Npc.NpcReply reply in chatpoint.Replies)
{ {
if(reply.RequiresQuestIdCompleted != 0)
if (user.Quests.GetTrackedQuestAmount(reply.RequiresQuestIdCompleted) <= 0)
continue;
if (reply.RequiresQuestIdNotCompleted != 0)
if (user.Quests.GetTrackedQuestAmount(reply.RequiresQuestIdCompleted) >= 1)
continue;
if (hideReplys)
continue;
message += Messages.FormatNpcReply(reply.ReplyText, reply.Id); message += Messages.FormatNpcReply(reply.ReplyText, reply.Id);
} }
message += Messages.BackToMap + Messages.MetaTerminator; message += Messages.BackToMap + Messages.MetaTerminator;
return message; return message;
} }
public static string BuildMetaInfo(int x, int y) public static string BuildMetaInfo(User user, int x, int y)
{ {
string message = ""; string message = "";
message += buildLocationString(x, y); message += buildLocationString(x, y);
Npc.NpcEntry[] entries = Npc.GetNpcByXAndY(x, y); message += buildNpc(user, x, y);
if (entries.Length > 0)
message += Messages.Seperator;
foreach (Npc.NpcEntry ent in entries)
message += Messages.FormatNpcStartChatMessage(ent.IconId, ent.Name, ent.ShortDescription, ent.Id);
message += buildCommonInfo(x, y); message += buildCommonInfo(x, y);
return message; return message;

View file

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Horse_Isle_Server namespace HISP.Game
{ {
class Npc class Npc
{ {

View file

@ -0,0 +1,194 @@
using System.Collections.Generic;
using System.IO;
using HISP.Player;
using HISP.Server;
namespace HISP.Game
{
class Quest
{
public const string Shovel = "SHOVEL";
public const string Binoculars = "BINOCS";
public const string Rake = "RAKE";
public const string MagnifyingGlass = "MAGNIFY";
public struct QuestItemInfo
{
public int ItemId;
public int Quantity;
}
public struct QuestAltActivation
{
public string Type;
public int ActivateX;
public int ActivateY;
}
public struct QuestEntry
{
public int Id;
public string Notes;
public string Title;
public int[] RequiresQuestIdComplete; // Not sure what this is for.
public QuestAltActivation AltActivation;
public bool Tracked; // Should we track how many times the player has completed this quest.
// Fail Settings
public int MaxRepeats;
public int MoneyCost;
public QuestItemInfo[] ItemsRequired;
public string FailNpcChat;
public int AwardRequired;
public int[] RequiresQuestIdCompleted;
public int[] RequiresQuestIdNotCompleted;
// Success Settings
public int MoneyEarned;
public QuestItemInfo[] ItemsEarned;
public int QuestPointsEarned;
public int GotoNpcChatpoint;
public int WarpX;
public int WarpY;
public string SuccessMessage;
public string SuccessNpcChat;
public bool HideReplyOnFail;
public string Difficulty;
public string Author;
public int ChainedQuestId;
public bool Minigame;
}
public static List<QuestEntry> QuestList = new List<QuestEntry>();
public static bool ActivateQuest(User user, QuestEntry quest, bool npcActivation = false)
{
if (quest.Tracked)
{
// Has completed other required quests?
foreach (int questId in quest.RequiresQuestIdCompleted)
if (user.Quests.GetTrackedQuestAmount(quest.Id) < 1)
goto Fail;
// Has NOT competed other MUST NOT BE required quests
foreach (int questId in quest.RequiresQuestIdNotCompleted)
if (user.Quests.GetTrackedQuestAmount(quest.Id) > 1)
goto Fail;
// Has allready tracked this quest?
if (user.Quests.GetTrackedQuestAmount(quest.Id) >= quest.MaxRepeats)
goto Fail;
}
// Check if i have required items
foreach (QuestItemInfo itemInfo in quest.ItemsRequired)
{
bool hasThisItem = false;
InventoryItem[] items = user.Inventory.GetItemList();
foreach (InventoryItem item in items)
{
if (item.ItemId == itemInfo.ItemId && item.ItemInstances.Count >= itemInfo.Quantity)
{
hasThisItem = true;
break;
}
}
if (!hasThisItem)
goto Fail;
}
// Have enough money?
if (user.Money < quest.MoneyCost)
goto Fail;
// Have required award (unimplemented)
goto Success;
Fail: {
if(quest.FailNpcChat != null)
{
if(!npcActivation)
{
byte[] ChatPacket = PacketBuilder.CreateChat(quest.FailNpcChat, PacketBuilder.CHAT_BOTTOM_RIGHT);
user.LoggedinClient.SendPacket(ChatPacket);
}
}
return false;
};
Success: {
// Take Items
foreach(QuestItemInfo itemInfo in quest.ItemsRequired)
{
InventoryItem itm = user.Inventory.GetItemByItemId(itemInfo.ItemId);
for(int i = 0; i < itemInfo.Quantity; i++)
user.Inventory.Remove(itm.ItemInstances[0]);
}
user.Money -= quest.MoneyCost;
// Give money
user.Money += quest.MoneyEarned;
// Give items
foreach (QuestItemInfo itemInfo in quest.ItemsEarned)
{
for (int i = 0; i < itemInfo.Quantity; i++)
{
ItemInstance itm = new ItemInstance(itemInfo.ItemId);
user.Inventory.Add(itm);
}
}
if (quest.WarpX != 0 && quest.WarpY != 0)
GameServer.Teleport(user.LoggedinClient, quest.WarpX, quest.WarpY);
// Give quest points
user.QuestPoints += quest.QuestPointsEarned;
if (quest.ChainedQuestId != 0)
ActivateQuest(user, GetQuestById(quest.ChainedQuestId));
if(quest.Tracked)
user.Quests.TrackQuest(quest.Id);
if(quest.SuccessNpcChat != null)
{
if (!npcActivation)
{
byte[] ChatPacket = PacketBuilder.CreateChat(quest.SuccessNpcChat, PacketBuilder.CHAT_BOTTOM_RIGHT);
user.LoggedinClient.SendPacket(ChatPacket);
}
}
if(quest.SuccessMessage != null)
{
byte[] ChatPacket = PacketBuilder.CreateChat(quest.SuccessMessage, PacketBuilder.CHAT_BOTTOM_RIGHT);
user.LoggedinClient.SendPacket(ChatPacket);
}
return true;
};
}
public static QuestEntry GetQuestById(int id)
{
foreach(QuestEntry quest in QuestList)
{
if(quest.Id == id)
{
return quest;
}
}
throw new KeyNotFoundException("QuestId: " + id + " Dont exist.");
}
public static bool UseTool(User user, string tool, int x, int y)
{
foreach(QuestEntry quest in QuestList)
{
if (quest.AltActivation.Type == tool && quest.AltActivation.ActivateX == x && quest.AltActivation.ActivateY == y)
{
ActivateQuest(user, quest);
return true;
}
}
return false;
}
}
}

View file

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Horse_Isle_Server namespace HISP.Game
{ {
class Transport class Transport
{ {

View file

@ -1,10 +1,7 @@
using System; using System.Collections.Generic;
using System.Collections.Generic; using HISP.Server;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server namespace HISP.Game
{ {
class World class World

View file

@ -6,7 +6,7 @@
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{C48CBD82-AB30-494A-8FFA-4DE7069B5827}</ProjectGuid> <ProjectGuid>{C48CBD82-AB30-494A-8FFA-4DE7069B5827}</ProjectGuid>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<RootNamespace>Horse_Isle_Server</RootNamespace> <RootNamespace>HISP</RootNamespace>
<AssemblyName>Horse Isle Server</AssemblyName> <AssemblyName>Horse Isle Server</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion> <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<LangVersion>8.0</LangVersion> <LangVersion>8.0</LangVersion>
@ -72,40 +72,42 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Action.cs" /> <Compile Include="Game\Quest.cs" />
<Compile Include="Authentication.cs" />
<Compile Include="Chat.cs" />
<Compile Include="Client.cs" />
<Compile Include="Converters.cs" />
<Compile Include="Database.cs" />
<Compile Include="Friends.cs" />
<Compile Include="Gamedata.cs" />
<Compile Include="IInventory.cs" />
<Compile Include="DroppedItems.cs" />
<Compile Include="ItemInstance.cs" />
<Compile Include="Logger.cs" />
<Compile Include="ConfigReader.cs" />
<Compile Include="CrossDomainPolicy.cs" />
<Compile Include="Mailbox.cs" />
<Compile Include="Map.cs" />
<Compile Include="Messages.cs" />
<Compile Include="Item.cs" />
<Compile Include="Meta.cs" />
<Compile Include="Npc.cs" />
<Compile Include="PacketBuilder.cs" />
<Compile Include="PlayerInventory.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Resources.Designer.cs"> <Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon> <DependentUpon>Resources.resx</DependentUpon>
</Compile> </Compile>
<Compile Include="RandomID.cs" /> <Compile Include="Security\Authentication.cs" />
<Compile Include="Server.cs" /> <Compile Include="Game\Chat.cs" />
<Compile Include="Transport.cs" /> <Compile Include="Server\GameClient.cs" />
<Compile Include="User.cs" /> <Compile Include="Server\Converters.cs" />
<Compile Include="World.cs" /> <Compile Include="Server\Database.cs" />
<Compile Include="Player\Friends.cs" />
<Compile Include="Server\Gamedata.cs" />
<Compile Include="Game\IInventory.cs" />
<Compile Include="Game\DroppedItems.cs" />
<Compile Include="Game\ItemInstance.cs" />
<Compile Include="Server\Logger.cs" />
<Compile Include="Server\ConfigReader.cs" />
<Compile Include="Security\CrossDomainPolicy.cs" />
<Compile Include="Player\Mailbox.cs" />
<Compile Include="Game\Map.cs" />
<Compile Include="Game\Messages.cs" />
<Compile Include="Game\Item.cs" />
<Compile Include="Game\Meta.cs" />
<Compile Include="Game\Npc.cs" />
<Compile Include="Server\PacketBuilder.cs" />
<Compile Include="Player\PlayerInventory.cs" />
<Compile Include="Player\PlayerQuests.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Security\RandomID.cs" />
<Compile Include="Server\GameServer.cs" />
<Compile Include="Player\TrackedQuest.cs" />
<Compile Include="Game\Transport.cs" />
<Compile Include="Player\User.cs" />
<Compile Include="Game\World.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="packages.config" /> <None Include="packages.config" />
@ -114,6 +116,7 @@
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Properties\Resources.resx"> <EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<SubType>Designer</SubType>
<LastGenOutput>Resources.Designer.cs</LastGenOutput> <LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>

View file

@ -1,10 +1,7 @@
using System; using System.Collections.Generic;
using System.Collections.Generic; using HISP.Server;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server namespace HISP.Player
{ {
class Friends class Friends
{ {

View file

@ -1,10 +1,6 @@
using System; using HISP.Server;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server namespace HISP.Player
{ {
class Mailbox class Mailbox
{ {

View file

@ -1,10 +1,9 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using HISP.Game;
using System.Threading.Tasks; using HISP.Server;
namespace Horse_Isle_Server namespace HISP.Player
{ {
class PlayerInventory : IInventory class PlayerInventory : IInventory
{ {

View file

@ -0,0 +1,53 @@
using System.Collections.Generic;
using HISP.Server;
namespace HISP.Player
{
class PlayerQuests
{
private List<TrackedQuest> trackedQuests = new List<TrackedQuest>();
public User BaseUser;
public TrackedQuest[] QuestList
{
get
{
return trackedQuests.ToArray();
}
}
public void Add(int questId, int timesCompleted)
{
TrackedQuest quest = new TrackedQuest(BaseUser.Id, questId, 0);
quest.TimesCompleted = timesCompleted;
trackedQuests.Add(quest);
}
public int GetTrackedQuestAmount(int questId)
{
foreach(TrackedQuest quest in QuestList)
{
if (quest.QuestId == questId)
return quest.TimesCompleted;
}
return 0;
}
public void TrackQuest(int questId)
{
foreach (TrackedQuest quest in QuestList)
{
if (quest.QuestId == questId)
{
quest.TimesCompleted++;
return;
}
}
Add(questId, 1);
}
public PlayerQuests(User user)
{
BaseUser = user;
TrackedQuest[] quests = Database.GetTrackedQuests(user.Id);
foreach (TrackedQuest quest in quests)
trackedQuests.Add(quest);
}
}
}

View file

@ -0,0 +1,30 @@
using System;
using HISP.Server;
namespace HISP
{
class TrackedQuest
{
public TrackedQuest(int playerID, int questID, int timesComplete)
{
playerId = playerID;
QuestId = questID;
timesCompleted = timesComplete;
}
public int QuestId;
private int playerId;
public int TimesCompleted
{
get
{
return timesCompleted;
}
set
{
Database.SetTrackedQuestCompletedCount(playerId, QuestId, value);
timesCompleted = value;
}
}
private int timesCompleted;
}
}

View file

@ -1,7 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using HISP.Game;
namespace Horse_Isle_Server using HISP.Server;
namespace HISP.Player
{ {
class User class User
{ {
@ -10,7 +11,7 @@ namespace Horse_Isle_Server
public bool Administrator; public bool Administrator;
public bool Moderator; public bool Moderator;
public bool NewPlayer = false; public bool NewPlayer = false;
public Client LoggedinClient; public GameClient LoggedinClient;
public bool MuteAds = false; public bool MuteAds = false;
public bool MuteGlobal = false; public bool MuteGlobal = false;
@ -31,6 +32,7 @@ namespace Horse_Isle_Server
public string Password; // For chat filter. public string Password; // For chat filter.
public PlayerInventory Inventory; public PlayerInventory Inventory;
public Npc.NpcEntry LastTalkedToNpc; public Npc.NpcEntry LastTalkedToNpc;
public PlayerQuests Quests;
public int ChatViolations public int ChatViolations
{ {
get get
@ -64,8 +66,21 @@ namespace Horse_Isle_Server
set set
{ {
Database.SetPlayerMoney(value, Id); Database.SetPlayerMoney(value, Id);
Server.UpdatePlayer(LoggedinClient);
money = value; money = value;
GameServer.UpdatePlayer(LoggedinClient);
}
}
public int QuestPoints
{
get
{
return questPoints;
}
set
{
Database.SetPlayerQuestPoints(value, Id);
questPoints = value;
} }
} }
@ -127,6 +142,7 @@ namespace Horse_Isle_Server
private int x; private int x;
private int y; private int y;
private int money; private int money;
private int questPoints;
private int bankMoney; private int bankMoney;
public byte[] SecCodeSeeds = new byte[3]; public byte[] SecCodeSeeds = new byte[3];
@ -152,7 +168,7 @@ namespace Horse_Isle_Server
return SecCode; return SecCode;
} }
public User(Client baseClient, int UserId) public User(GameClient baseClient, int UserId)
{ {
if (!Database.CheckUserExist(UserId)) if (!Database.CheckUserExist(UserId))
throw new KeyNotFoundException("User " + UserId + " not found in database!"); throw new KeyNotFoundException("User " + UserId + " not found in database!");
@ -178,6 +194,7 @@ namespace Horse_Isle_Server
money = Database.GetPlayerMoney(UserId); money = Database.GetPlayerMoney(UserId);
bankMoney = Database.GetPlayerBankMoney(UserId); bankMoney = Database.GetPlayerBankMoney(UserId);
questPoints = Database.GetPlayerQuestPoints(UserId);
profilePage = Database.GetPlayerProfile(UserId); profilePage = Database.GetPlayerProfile(UserId);
@ -198,6 +215,8 @@ namespace Horse_Isle_Server
LoggedinClient = baseClient; LoggedinClient = baseClient;
Inventory = new PlayerInventory(this); Inventory = new PlayerInventory(this);
Quests = new PlayerQuests(this);
} }
} }
} }

View file

@ -3,8 +3,10 @@ using System.Drawing;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using HISP.Game;
namespace Horse_Isle_Server using HISP.Security;
using HISP.Server;
namespace HISP
{ {
class Program class Program
{ {
@ -19,7 +21,7 @@ namespace Horse_Isle_Server
Gamedata.ReadGamedata(); Gamedata.ReadGamedata();
World.ReadWorldData(); World.ReadWorldData();
DroppedItems.Init(); DroppedItems.Init();
Server.StartServer(); GameServer.StartServer();
} }
} }

View file

@ -8,7 +8,7 @@
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace Horse_Isle_Server.Properties { namespace HISP.Properties {
using System; using System;
@ -39,7 +39,7 @@ namespace Horse_Isle_Server.Properties {
internal static global::System.Resources.ResourceManager ResourceManager { internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Horse_Isle_Server.Properties.Resources", typeof(Resources).Assembly); global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HISP.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
@ -62,7 +62,7 @@ namespace Horse_Isle_Server.Properties {
/// <summary> /// <summary>
/// Looks up a localized string similar to &lt;cross-domain-policy&gt; /// Looks up a localized string similar to &lt;cross-domain-policy&gt;
/// &lt;allow-access-from domain=&quot;*&quot; to-ports=&quot;1080&quot; secure=&quot;false&quot;/&gt; /// &lt;allow-access-from domain=&quot;*&quot; to-ports=&quot;12321&quot; secure=&quot;false&quot;/&gt;
///&lt;/cross-domain-policy&gt;. ///&lt;/cross-domain-policy&gt;.
/// </summary> /// </summary>
internal static string DefaultCrossDomain { internal static string DefaultCrossDomain {
@ -76,24 +76,28 @@ namespace Horse_Isle_Server.Properties {
/// ///
///# Ip address the server will bind to (default: 0.0.0.0 ALL INTERFACES) ///# Ip address the server will bind to (default: 0.0.0.0 ALL INTERFACES)
///ip=0.0.0.0 ///ip=0.0.0.0
///# Port the server will bind to (default: 1080) ///# Port the server will bind to (default: 12321)
///port=1080 ///port=12321
/// ///
///# MariaDB Database ///# MariaDB Database
///db_ip=127.0.0.1 ///db_ip=127.0.0.1
///db_name=beta
///db_username=root ///db_username=root
///db_password=test123 ///db_password=test123
///db_port=3306 ///db_port=3306
/// ///
///# Map Data ///# Map Data
///map=MapData.bmp ///map=HI1.MAP
///overlaymap=oMapData.bmp ///
///# JSON Format Data
///
///gamedata=gamedata.json
/// ///
///# Cross-Domain Policy File ///# Cross-Domain Policy File
///crossdomain=&quot;CrossDomainPolicy.xml ///crossdomain=CrossDomainPolicy.xml
/// ///
///# Should print debug logs ///# Red Text Stating &quot;Todays Note:&quot;
///debug=false. ///motd=April 11, 2020. New breed, C [rest of string was truncated]&quot;;.
/// </summary> /// </summary>
internal static string DefaultServerProperties { internal static string DefaultServerProperties {
get { get {

View file

@ -122,6 +122,6 @@
<value>..\Resources\default_cross_domain.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value> <value>..\Resources\default_cross_domain.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data> </data>
<data name="DefaultServerProperties" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="DefaultServerProperties" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\server.properties;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value> <value>..\Resources\Server.properties;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data> </data>
</root> </root>

View file

@ -18,8 +18,6 @@ map=HI1.MAP
# JSON Format Data # JSON Format Data
gamedata=gamedata.json gamedata=gamedata.json
npc=npc.json
quest=action.json
# Cross-Domain Policy File # Cross-Domain Policy File
crossdomain=CrossDomainPolicy.xml crossdomain=CrossDomainPolicy.xml

View file

@ -1,11 +1,9 @@
using System; using System.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Threading.Tasks; using HISP.Server;
namespace Horse_Isle_Server namespace HISP.Security
{ {
class Authentication class Authentication
{ {

View file

@ -1,12 +1,8 @@
using Horse_Isle_Server.Properties; using HISP.Properties;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using HISP.Server;
using System.Text; namespace HISP.Security
using System.Threading.Tasks;
namespace Horse_Isle_Server
{ {
class CrossDomainPolicy class CrossDomainPolicy
{ {

View file

@ -1,10 +1,5 @@
using System; using System;
using System.Collections.Generic; namespace HISP.Security
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server
{ {
class RandomID class RandomID
{ {

View file

@ -1,8 +1,7 @@
using Horse_Isle_Server.Properties; using HISP.Properties;
using System;
using System.IO; using System.IO;
namespace Horse_Isle_Server namespace HISP.Server
{ {
class ConfigReader class ConfigReader
@ -19,8 +18,6 @@ namespace Horse_Isle_Server
public static string Motd; public static string Motd;
public static string MapFile; public static string MapFile;
public static string GameDataFile; public static string GameDataFile;
public static string NpcDataFile;
public static string QuestDataFile;
public static string CrossDomainPolicyFile; public static string CrossDomainPolicyFile;
public static bool Debug; public static bool Debug;
@ -89,12 +86,6 @@ namespace Horse_Isle_Server
case "gamedata": case "gamedata":
GameDataFile = data; GameDataFile = data;
break; break;
case "npc":
NpcDataFile = data;
break;
case "quest":
QuestDataFile = data;
break;
case "crossdomain": case "crossdomain":
CrossDomainPolicyFile = data; CrossDomainPolicyFile = data;
break; break;

View file

@ -4,7 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Horse_Isle_Server namespace HISP.Server
{ {
class Converters class Converters
{ {

View file

@ -1,8 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using MySqlConnector; using MySqlConnector;
using HISP.Game;
namespace Horse_Isle_Server namespace HISP.Server
{ {
class Database class Database
{ {
@ -15,12 +16,13 @@ namespace Horse_Isle_Server
{ {
db.Open(); 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 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, ChatViolations INT)"; string ExtTable = "CREATE TABLE UserExt(Id INT, X INT, Y INT, Money INT, QuestPoints INT, BankBalance BIGINT,ProfilePage Text(1028), CharId INT, ChatViolations INT)";
string MailTable = "CREATE TABLE Mailbox(IdTo INT, PlayerFrom TEXT(16),Subject TEXT(128), Message Text(1028), TimeSent INT)"; 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 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 WorldTable = "CREATE TABLE World(Time INT,Day INT, Year INT, Weather TEXT(64))";
string InventoryTable = "CREATE TABLE Inventory(PlayerID INT, RandomID 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)"; string DroppedItems = "CREATE TABLE DroppedItems(X INT, Y INT, RandomID INT, ItemID INT, DespawnTimer INT)";
string TrackedQuest = "CREATE TABLE TrackedQuest(playerId INT, questId INT, timesCompleted INT)";
try try
{ {
@ -101,6 +103,19 @@ namespace Horse_Isle_Server
}; };
try
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = TrackedQuest;
sqlCommand.ExecuteNonQuery();
sqlCommand.Dispose();
}
catch (Exception e)
{
Logger.WarnPrint(e.Message);
};
try try
{ {
@ -265,6 +280,115 @@ namespace Horse_Isle_Server
return instances; return instances;
} }
} }
public static int GetTrackedQuestCompletedCount(int playerId, int questId)
{
if(CheckTrackeQuestExists(playerId,questId))
{
using (MySqlConnection db = new MySqlConnection(ConnectionString))
{
db.Open();
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT timesCompleted FROM TrackedQuest WHERE playerId=@playerId AND questId=@questId";
sqlCommand.Parameters.AddWithValue("@playerId", playerId);
sqlCommand.Parameters.AddWithValue("@questId", questId);
sqlCommand.Prepare();
int timesComplete = Convert.ToInt32(sqlCommand.ExecuteScalar());
sqlCommand.Dispose();
return timesComplete;
}
}
else
{
return 0;
}
}
public static bool CheckTrackeQuestExists(int playerId, int questId)
{
using (MySqlConnection db = new MySqlConnection(ConnectionString))
{
db.Open();
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT COUNT(*) FROM TrackedQuest WHERE playerId=@playerId AND questId=@questId";
sqlCommand.Parameters.AddWithValue("@playerId", playerId);
sqlCommand.Parameters.AddWithValue("@questId", questId);
sqlCommand.Prepare();
int count = Convert.ToInt32(sqlCommand.ExecuteScalar());
sqlCommand.Dispose();
if (count >= 1)
return true;
else
return false;
}
}
public static TrackedQuest[] GetTrackedQuests(int playerId)
{
List<TrackedQuest> trackedQuests = new List<TrackedQuest>();
using (MySqlConnection db = new MySqlConnection(ConnectionString))
{
db.Open();
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT questId,timesCompleted FROM TrackedQuest WHERE playerId=@playerId";
sqlCommand.Parameters.AddWithValue("@playerId", playerId);
sqlCommand.Prepare();
MySqlDataReader reader = sqlCommand.ExecuteReader();
while(reader.Read())
{
TrackedQuest trackedQuest = new TrackedQuest(playerId, reader.GetInt32(0), reader.GetInt32(1));
trackedQuests.Add(trackedQuest);
}
sqlCommand.Dispose();
}
return trackedQuests.ToArray();
}
public static void SetTrackedQuestCompletedCount(int playerId, int questId, int timesCompleted)
{
if(CheckTrackeQuestExists(playerId,questId))
{
using (MySqlConnection db = new MySqlConnection(ConnectionString))
{
db.Open();
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "UPDATE TrackedQuest SET timesCompleted=@timesCompleted WHERE playerId=@playerId AND questId=@questId";
sqlCommand.Parameters.AddWithValue("@playerId", playerId);
sqlCommand.Parameters.AddWithValue("@questId", questId);
sqlCommand.Parameters.AddWithValue("@timesCompleted", timesCompleted);
sqlCommand.Prepare();
sqlCommand.ExecuteNonQuery();
sqlCommand.Dispose();
}
}
else
{
AddNewTrackedQuest(playerId, questId, timesCompleted);
}
}
public static void AddNewTrackedQuest(int playerId, int questId, int timesCompleted)
{
using (MySqlConnection db = new MySqlConnection(ConnectionString))
{
db.Open();
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "INSERT INTO TrackedQuest VALUES(@playerId,@questId,@timesCompleted)";
sqlCommand.Parameters.AddWithValue("@playerId", playerId);
sqlCommand.Parameters.AddWithValue("@questId", questId);
sqlCommand.Parameters.AddWithValue("@timesCompleted", timesCompleted);
sqlCommand.Prepare();
sqlCommand.ExecuteNonQuery();
sqlCommand.Dispose();
}
}
public static void AddItemToInventory(int playerId, ItemInstance instance) public static void AddItemToInventory(int playerId, ItemInstance instance)
{ {
using (MySqlConnection db = new MySqlConnection(ConnectionString)) using (MySqlConnection db = new MySqlConnection(ConnectionString))
@ -595,7 +719,7 @@ namespace Horse_Isle_Server
throw new Exception("Userid " + id + " Allready in userext."); throw new Exception("Userid " + id + " Allready in userext.");
MySqlCommand sqlCommand = db.CreateCommand(); MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "INSERT INTO UserExt VALUES(@id,@x,@y,0,0,'',0,0)"; sqlCommand.CommandText = "INSERT INTO UserExt VALUES(@id,@x,@y,0,0,0,'',0,0)";
sqlCommand.Parameters.AddWithValue("@id", id); sqlCommand.Parameters.AddWithValue("@id", id);
sqlCommand.Parameters.AddWithValue("@x", Map.NewUserStartX); sqlCommand.Parameters.AddWithValue("@x", Map.NewUserStartX);
sqlCommand.Parameters.AddWithValue("@y", Map.NewUserStartY); sqlCommand.Parameters.AddWithValue("@y", Map.NewUserStartY);
@ -813,6 +937,51 @@ namespace Horse_Isle_Server
} }
} }
public static void SetPlayerQuestPoints(int qp, int id)
{
using (MySqlConnection db = new MySqlConnection(ConnectionString))
{
db.Open();
if (CheckUserExist(id))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "UPDATE UserExt SET QuestPoints=@questPoints WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@questPoints", qp);
sqlCommand.Parameters.AddWithValue("@id", id);
sqlCommand.Prepare();
sqlCommand.ExecuteNonQuery();
sqlCommand.Dispose();
}
else
{
throw new KeyNotFoundException("Id " + id + " not found in database.");
}
}
}
public static int GetPlayerQuestPoints(int userId)
{
using (MySqlConnection db = new MySqlConnection(ConnectionString))
{
db.Open();
if (CheckUserExtExists(userId))
{
MySqlCommand sqlCommand = db.CreateCommand();
sqlCommand.CommandText = "SELECT QuestPoints FROM UserExt WHERE Id=@id";
sqlCommand.Parameters.AddWithValue("@id", userId);
sqlCommand.Prepare();
int QuestPoints = Convert.ToInt32(sqlCommand.ExecuteScalar());
sqlCommand.Dispose();
return QuestPoints;
}
else
{
throw new KeyNotFoundException("Id " + userId + " not found in database.");
}
}
}
public static void SetPlayerMoney(int money, int id) public static void SetPlayerMoney(int money, int id)
{ {
using (MySqlConnection db = new MySqlConnection(ConnectionString)) using (MySqlConnection db = new MySqlConnection(ConnectionString))

View file

@ -3,9 +3,12 @@ using System.IO;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
namespace Horse_Isle_Server using HISP.Player;
using HISP.Game;
namespace HISP.Server
{ {
class Client class GameClient
{ {
public Socket ClientSocket; public Socket ClientSocket;
public string RemoteIp; public string RemoteIp;
@ -25,8 +28,8 @@ namespace Horse_Isle_Server
private int keepAliveInterval = 60 * 1000; private int keepAliveInterval = 60 * 1000;
private int updateInterval = 60 * 1000; private int updateInterval = 60 * 1000;
private int warnInterval = Server.IdleWarning * 60 * 1000; private int warnInterval = GameServer.IdleWarning * 60 * 1000;
private int kickInterval = Server.IdleTimeout * 60 * 1000; private int kickInterval = GameServer.IdleTimeout * 60 * 1000;
private void keepAliveTimerTick(object state) private void keepAliveTimerTick(object state)
@ -49,8 +52,8 @@ namespace Horse_Isle_Server
} }
private void updateTimerTick(object state) private void updateTimerTick(object state)
{ {
Server.UpdateWorld(this); GameServer.UpdateWorld(this);
Server.UpdatePlayer(this); GameServer.UpdatePlayer(this);
} }
public void Login(int id) public void Login(int id)
{ {
@ -126,12 +129,12 @@ namespace Horse_Isle_Server
{ {
if (Encoding.UTF8.GetString(Packet).StartsWith("<policy-file-request/>")) // Policy File Request if (Encoding.UTF8.GetString(Packet).StartsWith("<policy-file-request/>")) // Policy File Request
{ {
Server.OnCrossdomainPolicyRequest(this); GameServer.OnCrossdomainPolicyRequest(this);
} }
switch (identifier) switch (identifier)
{ {
case PacketBuilder.PACKET_LOGIN: case PacketBuilder.PACKET_LOGIN:
Server.OnLoginRequest(this, Packet); GameServer.OnLoginRequest(this, Packet);
break; break;
} }
} }
@ -140,31 +143,31 @@ namespace Horse_Isle_Server
switch (identifier) switch (identifier)
{ {
case PacketBuilder.PACKET_LOGIN: case PacketBuilder.PACKET_LOGIN:
Server.OnUserInfoRequest(this, Packet); GameServer.OnUserInfoRequest(this, Packet);
break; break;
case PacketBuilder.PACKET_MOVE: case PacketBuilder.PACKET_MOVE:
Server.OnMovementPacket(this, Packet); GameServer.OnMovementPacket(this, Packet);
break; break;
case PacketBuilder.PACKET_PROFILE: case PacketBuilder.PACKET_PROFILE:
Server.OnProfilePacket(this, Packet); GameServer.OnProfilePacket(this, Packet);
break; break;
case PacketBuilder.PACKET_CHAT: case PacketBuilder.PACKET_CHAT:
Server.OnChatPacket(this, Packet); GameServer.OnChatPacket(this, Packet);
break; break;
case PacketBuilder.PACKET_KEEP_ALIVE: case PacketBuilder.PACKET_KEEP_ALIVE:
Server.OnKeepAlive(this, Packet); GameServer.OnKeepAlive(this, Packet);
break; break;
case PacketBuilder.PACKET_TRANSPORT: case PacketBuilder.PACKET_TRANSPORT:
Server.OnTransportUsed(this, Packet); GameServer.OnTransportUsed(this, Packet);
break; break;
case PacketBuilder.PACKET_INVENTORY: case PacketBuilder.PACKET_INVENTORY:
Server.OnInventoryRequested(this, Packet); GameServer.OnInventoryRequested(this, Packet);
break; break;
case PacketBuilder.PACKET_ITEM_INTERACTION: case PacketBuilder.PACKET_ITEM_INTERACTION:
Server.OnItemInteraction(this,Packet); GameServer.OnItemInteraction(this,Packet);
break; break;
case PacketBuilder.PACKET_NPC: case PacketBuilder.PACKET_NPC:
Server.OnNpcInteraction(this, Packet); GameServer.OnNpcInteraction(this, Packet);
break; break;
default: default:
Logger.ErrorPrint("Unimplemented Packet: " + BitConverter.ToString(Packet).Replace('-', ' ')); Logger.ErrorPrint("Unimplemented Packet: " + BitConverter.ToString(Packet).Replace('-', ' '));
@ -186,7 +189,7 @@ namespace Horse_Isle_Server
if(kickTimer != null) if(kickTimer != null)
kickTimer.Dispose(); kickTimer.Dispose();
Server.OnDisconnect(this); GameServer.OnDisconnect(this);
LoggedIn = false; LoggedIn = false;
LoggedinUser = null; LoggedinUser = null;
ClientSocket.Close(); ClientSocket.Close();
@ -215,7 +218,7 @@ namespace Horse_Isle_Server
} }
} }
public Client(Socket clientSocket) public GameClient(Socket clientSocket)
{ {
ClientSocket = clientSocket; ClientSocket = clientSocket;
RemoteIp = clientSocket.RemoteEndPoint.ToString(); RemoteIp = clientSocket.RemoteEndPoint.ToString();

View file

@ -1,22 +1,23 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using HISP.Player;
using HISP.Game;
using HISP.Security;
namespace Horse_Isle_Server namespace HISP.Server
{ {
class Server class GameServer
{ {
public static Socket ServerSocket; public static Socket ServerSocket;
private static Timer serverTimer; private static Timer serverTimer;
public static Client[] ConnectedClients // Done to prevent Enumerator Changed errors. public static GameClient[] ConnectedClients // Done to prevent Enumerator Changed errors.
{ {
get { get {
return connectedClients.ToArray(); return connectedClients.ToArray();
@ -31,8 +32,8 @@ namespace Horse_Isle_Server
// used for world time, // used for world time,
private static int gameTickSpeed = 4320; // Changing this to ANYTHING else will cause desync with the client. private static int gameTickSpeed = 4320; // Changing this to ANYTHING else will cause desync with the client.
private static List<Client> connectedClients = new List<Client>(); private static List<GameClient> connectedClients = new List<GameClient>();
public static void OnCrossdomainPolicyRequest(Client sender) // When a cross-domain-policy request is received. public static void OnCrossdomainPolicyRequest(GameClient sender) // When a cross-domain-policy request is received.
{ {
Logger.DebugPrint("Cross-Domain-Policy request received from: " + sender.RemoteIp); Logger.DebugPrint("Cross-Domain-Policy request received from: " + sender.RemoteIp);
@ -41,7 +42,7 @@ namespace Horse_Isle_Server
sender.SendPacket(crossDomainPolicyResponse); // Send to client. sender.SendPacket(crossDomainPolicyResponse); // Send to client.
} }
public static void OnUserInfoRequest(Client sender, byte[] packet) public static void OnUserInfoRequest(GameClient sender, byte[] packet)
{ {
if (!sender.LoggedIn) if (!sender.LoggedIn)
{ {
@ -64,12 +65,12 @@ namespace Horse_Isle_Server
byte[] SecCodePacket = PacketBuilder.CreateSecCode(user.SecCodeSeeds, user.SecCodeInc, user.Administrator, user.Moderator); byte[] SecCodePacket = PacketBuilder.CreateSecCode(user.SecCodeSeeds, user.SecCodeInc, user.Administrator, user.Moderator);
sender.SendPacket(SecCodePacket); sender.SendPacket(SecCodePacket);
byte[] BaseStatsPacketData = PacketBuilder.CreatePlayerData(user.Money, Server.GetNumberOfPlayers(), user.MailBox.MailCount); byte[] BaseStatsPacketData = PacketBuilder.CreatePlayerData(user.Money, GameServer.GetNumberOfPlayers(), user.MailBox.MailCount);
sender.SendPacket(BaseStatsPacketData); sender.SendPacket(BaseStatsPacketData);
UpdateArea(sender); UpdateArea(sender);
foreach (Client client in ConnectedClients) foreach (GameClient client in ConnectedClients)
{ {
if (client.LoggedIn) if (client.LoggedIn)
{ {
@ -81,7 +82,7 @@ namespace Horse_Isle_Server
} }
} }
foreach (User nearbyUser in Server.GetNearbyUsers(sender.LoggedinUser.X, sender.LoggedinUser.Y, false, false)) foreach (User nearbyUser in GameServer.GetNearbyUsers(sender.LoggedinUser.X, sender.LoggedinUser.Y, false, false))
if (nearbyUser.Id != sender.LoggedinUser.Id) if (nearbyUser.Id != sender.LoggedinUser.Id)
UpdateArea(nearbyUser.LoggedinClient); UpdateArea(nearbyUser.LoggedinClient);
@ -97,7 +98,7 @@ namespace Horse_Isle_Server
} }
public static void OnKeepAlive(Client sender, byte[] packet) public static void OnKeepAlive(GameClient sender, byte[] packet)
{ {
if (!sender.LoggedIn) if (!sender.LoggedIn)
{ {
@ -116,7 +117,7 @@ namespace Horse_Isle_Server
UpdatePlayer(sender); UpdatePlayer(sender);
} }
} }
public static void OnProfilePacket(Client sender, byte[] packet) public static void OnProfilePacket(GameClient sender, byte[] packet)
{ {
if (!sender.LoggedIn) if (!sender.LoggedIn)
{ {
@ -164,7 +165,7 @@ namespace Horse_Isle_Server
} }
public static void OnMovementPacket(Client sender, byte[] packet) public static void OnMovementPacket(GameClient sender, byte[] packet)
{ {
if (!sender.LoggedIn) if (!sender.LoggedIn)
{ {
@ -219,8 +220,7 @@ namespace Horse_Isle_Server
Direction = PacketBuilder.DIRECTION_DOWN; Direction = PacketBuilder.DIRECTION_DOWN;
} }
if (loggedInUser.X == 0 && loggedInUser.Y == 0)
Logger.ErrorPrint("Impossible bug occured.");
Logger.DebugPrint("Exiting player: " + loggedInUser.Username + " to: " + loggedInUser.X + "," + loggedInUser.Y); Logger.DebugPrint("Exiting player: " + loggedInUser.Username + " to: " + loggedInUser.X + "," + loggedInUser.Y);
byte[] moveResponse = PacketBuilder.CreateMovementPacket(loggedInUser.X, loggedInUser.Y, loggedInUser.CharacterId, Direction, Direction, true); byte[] moveResponse = PacketBuilder.CreateMovementPacket(loggedInUser.X, loggedInUser.Y, loggedInUser.CharacterId, Direction, Direction, true);
sender.SendPacket(moveResponse); sender.SendPacket(moveResponse);
@ -297,7 +297,7 @@ namespace Horse_Isle_Server
Update(sender); Update(sender);
} }
public static void OnNpcInteraction(Client sender, byte[] packet) public static void OnNpcInteraction(GameClient sender, byte[] packet)
{ {
if (!sender.LoggedIn) if (!sender.LoggedIn)
{ {
@ -325,9 +325,8 @@ namespace Horse_Isle_Server
Logger.ErrorPrint(sender.LoggedinUser.Username + " Tried to start talking to an NPC with id that is NaN."); Logger.ErrorPrint(sender.LoggedinUser.Username + " Tried to start talking to an NPC with id that is NaN.");
return; return;
} }
Npc.NpcEntry entry = Npc.GetNpcById(chatId); Npc.NpcEntry entry = Npc.GetNpcById(chatId);
string metaInfo = Meta.BuildChatpoint(entry, entry.Chatpoints[0]); string metaInfo = Meta.BuildChatpoint(sender.LoggedinUser, entry, entry.Chatpoints[0]);
byte[] metaPacket = PacketBuilder.CreateMetaPacket(metaInfo); byte[] metaPacket = PacketBuilder.CreateMetaPacket(metaInfo);
sender.SendPacket(metaPacket); sender.SendPacket(metaPacket);
@ -365,8 +364,7 @@ namespace Horse_Isle_Server
UpdateArea(sender,true); UpdateArea(sender,true);
return; return;
} }
string metaInfo = Meta.BuildChatpoint(sender.LoggedinUser, lastNpc, Npc.GetNpcChatpoint(lastNpc, reply.GotoChatpoint));
string metaInfo = Meta.BuildChatpoint(npc,Npc.GetNpcChatpoint(lastNpc, reply.GotoChatpoint));
byte[] metaPacket = PacketBuilder.CreateMetaPacket(metaInfo); byte[] metaPacket = PacketBuilder.CreateMetaPacket(metaInfo);
sender.SendPacket(metaPacket); sender.SendPacket(metaPacket);
return; return;
@ -375,7 +373,7 @@ namespace Horse_Isle_Server
} }
} }
public static void OnTransportUsed(Client sender, byte[] packet) public static void OnTransportUsed(GameClient sender, byte[] packet)
{ {
if (!sender.LoggedIn) if (!sender.LoggedIn)
{ {
@ -448,7 +446,7 @@ namespace Horse_Isle_Server
} }
public static void OnChatPacket(Client sender, byte[] packet) public static void OnChatPacket(GameClient sender, byte[] packet)
{ {
if (!sender.LoggedIn) if (!sender.LoggedIn)
{ {
@ -504,7 +502,7 @@ namespace Horse_Isle_Server
return; return;
} }
Client[] recipiants = Chat.GetRecipiants(sender.LoggedinUser, channel, nameTo); GameClient[] recipiants = Chat.GetRecipiants(sender.LoggedinUser, channel, nameTo);
// Finally send chat message. // Finally send chat message.
string formattedMessage = Chat.FormatChatForOthers(sender.LoggedinUser, channel, message); string formattedMessage = Chat.FormatChatForOthers(sender.LoggedinUser, channel, message);
@ -513,7 +511,7 @@ namespace Horse_Isle_Server
byte[] chatPacketSender = PacketBuilder.CreateChat(formattedMessageSender, chatSide); byte[] chatPacketSender = PacketBuilder.CreateChat(formattedMessageSender, chatSide);
byte[] playDmSound = PacketBuilder.CreatePlaysoundPacket(Chat.PrivateMessageSound); byte[] playDmSound = PacketBuilder.CreatePlaysoundPacket(Chat.PrivateMessageSound);
// Send to clients ... // Send to clients ...
foreach (Client recipiant in recipiants) foreach (GameClient recipiant in recipiants)
{ {
recipiant.SendPacket(chatPacketOthers); recipiant.SendPacket(chatPacketOthers);
if (channel == Chat.ChatChannel.Dm) if (channel == Chat.ChatChannel.Dm)
@ -524,7 +522,7 @@ namespace Horse_Isle_Server
sender.SendPacket(chatPacketSender); sender.SendPacket(chatPacketSender);
} }
public static void OnItemInteraction(Client sender, byte[] packet) public static void OnItemInteraction(GameClient sender, byte[] packet)
{ {
if (!sender.LoggedIn) if (!sender.LoggedIn)
{ {
@ -603,7 +601,42 @@ namespace Horse_Isle_Server
Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to drop an item they did not have."); Logger.HackerPrint(sender.LoggedinUser.Username + " Tried to drop an item they did not have.");
} }
break; break;
case PacketBuilder.ITEM_SHOVEL:
if (packet[2] != 0x14)
Logger.HackerPrint(sender.LoggedinUser.Username + " Used ITEM_SHOVEL with 3rd byte not 0x14.");
if (!Quest.UseTool(sender.LoggedinUser, Quest.Shovel, sender.LoggedinUser.X, sender.LoggedinUser.Y))
{
byte[] ChatPacket = PacketBuilder.CreateChat(Messages.ShovelNothing, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(ChatPacket);
}
break;
case PacketBuilder.ITEM_RAKE:
if (packet[2] != 0x14)
Logger.HackerPrint(sender.LoggedinUser.Username + " Used ITEM_RAKE with 3rd byte not 0x14.");
if (!Quest.UseTool(sender.LoggedinUser, Quest.Rake, sender.LoggedinUser.X, sender.LoggedinUser.Y))
{
byte[] ChatPacket = PacketBuilder.CreateChat(Messages.RakeNothing, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(ChatPacket);
}
break;
case PacketBuilder.ITEM_MAGNIFYING:
if (packet[2] != 0x14)
Logger.HackerPrint(sender.LoggedinUser.Username + " Used ITEM_MAGNIFYING with 3rd byte not 0x14.");
if (!Quest.UseTool(sender.LoggedinUser, Quest.MagnifyingGlass, sender.LoggedinUser.X, sender.LoggedinUser.Y))
{
byte[] ChatPacket = PacketBuilder.CreateChat(Messages.MagnifyNothing, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(ChatPacket);
}
break;
case PacketBuilder.ITEM_BINOCULARS:
if (packet[2] != 0x14)
Logger.HackerPrint(sender.LoggedinUser.Username + " Used ITEM_BINOCULARS with 3rd byte not 0x14.");
if(!Quest.UseTool(sender.LoggedinUser, Quest.Binoculars, sender.LoggedinUser.X, sender.LoggedinUser.Y))
{
byte[] ChatPacket = PacketBuilder.CreateChat(Messages.BinocularsNothing, PacketBuilder.CHAT_BOTTOM_RIGHT);
sender.SendPacket(ChatPacket);
}
break;
default: default:
Logger.WarnPrint(sender.LoggedinUser.Username + " Sent an unknown Item Interaction Packet type: " + action.ToString() + ", Packet Dump: " + BitConverter.ToString(packet).Replace('-', ' ')); Logger.WarnPrint(sender.LoggedinUser.Username + " Sent an unknown Item Interaction Packet type: " + action.ToString() + ", Packet Dump: " + BitConverter.ToString(packet).Replace('-', ' '));
break; break;
@ -611,7 +644,7 @@ namespace Horse_Isle_Server
} }
public static void OnInventoryRequested(Client sender, byte[] packet) public static void OnInventoryRequested(GameClient sender, byte[] packet)
{ {
if (!sender.LoggedIn) if (!sender.LoggedIn)
{ {
@ -627,7 +660,7 @@ namespace Horse_Isle_Server
UpdateInventory(sender); UpdateInventory(sender);
} }
public static void OnLoginRequest(Client sender, byte[] packet) public static void OnLoginRequest(GameClient sender, byte[] packet)
{ {
Logger.DebugPrint("Login request received from: " + sender.RemoteIp); Logger.DebugPrint("Login request received from: " + sender.RemoteIp);
@ -668,7 +701,7 @@ namespace Horse_Isle_Server
// Send login message // Send login message
byte[] loginMessageBytes = PacketBuilder.CreateChat(Messages.FormatLoginMessage(sender.LoggedinUser.Username), PacketBuilder.CHAT_BOTTOM_LEFT); byte[] loginMessageBytes = PacketBuilder.CreateChat(Messages.FormatLoginMessage(sender.LoggedinUser.Username), PacketBuilder.CHAT_BOTTOM_LEFT);
foreach (Client client in ConnectedClients) foreach (GameClient client in ConnectedClients)
if (client.LoggedIn) if (client.LoggedIn)
if (!client.LoggedinUser.MuteLogins) if (!client.LoggedinUser.MuteLogins)
if (client.LoggedinUser.Id != userId) if (client.LoggedinUser.Id != userId)
@ -689,7 +722,7 @@ namespace Horse_Isle_Server
public static void OnDisconnect(Client sender) public static void OnDisconnect(GameClient sender)
{ {
connectedClients.Remove(sender); connectedClients.Remove(sender);
@ -697,14 +730,14 @@ namespace Horse_Isle_Server
{ {
// Send disconnect message // Send disconnect message
byte[] logoutMessageBytes = PacketBuilder.CreateChat(Messages.FormatLogoutMessage(sender.LoggedinUser.Username), PacketBuilder.CHAT_BOTTOM_LEFT); byte[] logoutMessageBytes = PacketBuilder.CreateChat(Messages.FormatLogoutMessage(sender.LoggedinUser.Username), PacketBuilder.CHAT_BOTTOM_LEFT);
foreach (Client client in ConnectedClients) foreach (GameClient client in ConnectedClients)
if (client.LoggedIn) if (client.LoggedIn)
if (!client.LoggedinUser.MuteLogins) if (!client.LoggedinUser.MuteLogins)
if (client.LoggedinUser.Id != sender.LoggedinUser.Id) if (client.LoggedinUser.Id != sender.LoggedinUser.Id)
client.SendPacket(logoutMessageBytes); client.SendPacket(logoutMessageBytes);
// Tell clients of diconnect (remove from chat) // Tell clients of diconnect (remove from chat)
byte[] playerRemovePacket = PacketBuilder.CreatePlayerLeavePacket(sender.LoggedinUser.Username); byte[] playerRemovePacket = PacketBuilder.CreatePlayerLeavePacket(sender.LoggedinUser.Username);
foreach (Client client in ConnectedClients) foreach (GameClient client in ConnectedClients)
if (client.LoggedIn) if (client.LoggedIn)
if (client.LoggedinUser.Id != sender.LoggedinUser.Id) if (client.LoggedinUser.Id != sender.LoggedinUser.Id)
client.SendPacket(playerRemovePacket); client.SendPacket(playerRemovePacket);
@ -716,7 +749,7 @@ namespace Horse_Isle_Server
public static User[] GetUsersUsersInIsle(World.Isle isle, bool includeStealth = false, bool includeMuted = false) public static User[] GetUsersUsersInIsle(World.Isle isle, bool includeStealth = false, bool includeMuted = false)
{ {
List<User> usersInIsle = new List<User>(); List<User> usersInIsle = new List<User>();
foreach (Client client in ConnectedClients) foreach (GameClient client in ConnectedClients)
if (client.LoggedIn) if (client.LoggedIn)
{ {
if (!includeStealth && client.LoggedinUser.Stealth) if (!includeStealth && client.LoggedinUser.Stealth)
@ -734,7 +767,7 @@ namespace Horse_Isle_Server
public static User[] GetUsersAt(int x, int y, bool includeStealth = false, bool includeMuted = false) public static User[] GetUsersAt(int x, int y, bool includeStealth = false, bool includeMuted = false)
{ {
List<User> usersHere = new List<User>(); List<User> usersHere = new List<User>();
foreach(Client client in ConnectedClients) foreach(GameClient client in ConnectedClients)
{ {
if(client.LoggedIn) if(client.LoggedIn)
{ {
@ -757,7 +790,7 @@ namespace Horse_Isle_Server
int endY = y + 19; int endY = y + 19;
List<User> usersNearby = new List<User>(); List<User> usersNearby = new List<User>();
foreach (Client client in ConnectedClients) foreach (GameClient client in ConnectedClients)
if (client.LoggedIn) if (client.LoggedIn)
{ {
if (!includeStealth && client.LoggedinUser.Stealth) if (!includeStealth && client.LoggedinUser.Stealth)
@ -774,7 +807,7 @@ namespace Horse_Isle_Server
public static int GetNumberOfPlayers(bool includeStealth=false) public static int GetNumberOfPlayers(bool includeStealth=false)
{ {
int count = 0; int count = 0;
foreach(Client client in ConnectedClients) foreach(GameClient client in ConnectedClients)
if (client.LoggedIn) if (client.LoggedIn)
{ {
if (!includeStealth && client.LoggedinUser.Stealth) if (!includeStealth && client.LoggedinUser.Stealth)
@ -789,7 +822,7 @@ namespace Horse_Isle_Server
public static int GetNumberOfModsOnline() public static int GetNumberOfModsOnline()
{ {
int count = 0; int count = 0;
foreach (Client client in ConnectedClients) foreach (GameClient client in ConnectedClients)
{ {
if (client.LoggedIn) if (client.LoggedIn)
if(client.LoggedinUser.Moderator) if(client.LoggedinUser.Moderator)
@ -798,7 +831,7 @@ namespace Horse_Isle_Server
return count; return count;
} }
public static void Teleport(Client client, int newX, int newY) public static void Teleport(GameClient client, int newX, int newY)
{ {
if (!client.LoggedIn) if (!client.LoggedIn)
return; return;
@ -812,24 +845,24 @@ namespace Horse_Isle_Server
Update(client); Update(client);
} }
public static void Update(Client client, bool justArea = false) public static void Update(GameClient client, bool justArea = false)
{ {
UpdateArea(client, justArea); UpdateArea(client, justArea);
foreach (User nearbyUser in Server.GetNearbyUsers(client.LoggedinUser.X, client.LoggedinUser.Y, false, false)) foreach (User nearbyUser in GameServer.GetNearbyUsers(client.LoggedinUser.X, client.LoggedinUser.Y, false, false))
if (nearbyUser.Id != client.LoggedinUser.Id) if (nearbyUser.Id != client.LoggedinUser.Id)
UpdateArea(nearbyUser.LoggedinClient, justArea); UpdateArea(nearbyUser.LoggedinClient, justArea);
UpdateUserInfo(client.LoggedinUser); UpdateUserInfo(client.LoggedinUser);
} }
public static void UpdateInventory(Client forClient) public static void UpdateInventory(GameClient forClient)
{ {
if (!forClient.LoggedIn) if (!forClient.LoggedIn)
return; return;
byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildInventoryInfo(forClient.LoggedinUser.Inventory)); byte[] metaPacket = PacketBuilder.CreateMetaPacket(Meta.BuildInventoryInfo(forClient.LoggedinUser.Inventory));
forClient.SendPacket(metaPacket); forClient.SendPacket(metaPacket);
} }
public static void UpdateWorld(Client forClient) public static void UpdateWorld(GameClient forClient)
{ {
if (!forClient.LoggedIn) if (!forClient.LoggedIn)
{ {
@ -841,14 +874,14 @@ namespace Horse_Isle_Server
forClient.SendPacket(WorldData); forClient.SendPacket(WorldData);
} }
public static void UpdatePlayer(Client forClient) public static void UpdatePlayer(GameClient forClient)
{ {
if (!forClient.LoggedIn) if (!forClient.LoggedIn)
{ {
Logger.ErrorPrint(forClient.RemoteIp + "tried to update player information when not logged in."); Logger.ErrorPrint(forClient.RemoteIp + "tried to update player information when not logged in.");
return; return;
} }
byte[] PlayerData = PacketBuilder.CreatePlayerData(forClient.LoggedinUser.Money, Server.GetNumberOfPlayers(), forClient.LoggedinUser.MailBox.MailCount); byte[] PlayerData = PacketBuilder.CreatePlayerData(forClient.LoggedinUser.Money, GameServer.GetNumberOfPlayers(), forClient.LoggedinUser.MailBox.MailCount);
forClient.SendPacket(PlayerData); forClient.SendPacket(PlayerData);
} }
@ -859,7 +892,7 @@ namespace Horse_Isle_Server
List<User> users = new List<User>(); List<User> users = new List<User>();
foreach (Client client in ConnectedClients) foreach (GameClient client in ConnectedClients)
if (client.LoggedIn) if (client.LoggedIn)
{ {
if (client.LoggedinUser.Id != user.Id) if (client.LoggedinUser.Id != user.Id)
@ -871,14 +904,14 @@ namespace Horse_Isle_Server
public static void UpdateAreaForAll(int x, int y) public static void UpdateAreaForAll(int x, int y)
{ {
foreach(Client client in ConnectedClients) foreach(GameClient client in ConnectedClients)
{ {
if (client.LoggedIn) if (client.LoggedIn)
if (client.LoggedinUser.X == x && client.LoggedinUser.Y == y) if (client.LoggedinUser.X == x && client.LoggedinUser.Y == y)
UpdateArea(client, true); UpdateArea(client, true);
} }
} }
public static void UpdateArea(Client forClient, bool justArea = false) public static void UpdateArea(GameClient forClient, bool justArea = false)
{ {
if (!forClient.LoggedIn) if (!forClient.LoggedIn)
{ {
@ -889,7 +922,7 @@ namespace Horse_Isle_Server
string LocationStr = ""; string LocationStr = "";
if (!World.InSpecialTile(forClient.LoggedinUser.X, forClient.LoggedinUser.Y)) if (!World.InSpecialTile(forClient.LoggedinUser.X, forClient.LoggedinUser.Y))
{ {
LocationStr = Meta.BuildMetaInfo(forClient.LoggedinUser.X, forClient.LoggedinUser.Y); LocationStr = Meta.BuildMetaInfo(forClient.LoggedinUser, forClient.LoggedinUser.X, forClient.LoggedinUser.Y);
} }
else else
{ {
@ -902,14 +935,14 @@ namespace Horse_Isle_Server
if (specialTile.Code != null && !justArea) if (specialTile.Code != null && !justArea)
if (!ProcessMapCodeWithArg(forClient, specialTile.Code)) if (!ProcessMapCodeWithArg(forClient, specialTile.Code))
return; return;
LocationStr = Meta.BuildSpecialTileInfo(specialTile); LocationStr = Meta.BuildSpecialTileInfo(forClient.LoggedinUser, specialTile);
} }
byte[] AreaMessage = PacketBuilder.CreateMetaPacket(LocationStr); byte[] AreaMessage = PacketBuilder.CreateMetaPacket(LocationStr);
forClient.SendPacket(AreaMessage); forClient.SendPacket(AreaMessage);
} }
public static bool ProcessMapCodeWithArg(Client forClient, string mapCode) public static bool ProcessMapCodeWithArg(GameClient forClient, string mapCode)
{ {
if(mapCode.Contains('-')) if(mapCode.Contains('-'))
{ {
@ -943,7 +976,7 @@ namespace Horse_Isle_Server
public static int GetNumberOfAdminsOnline() public static int GetNumberOfAdminsOnline()
{ {
int count = 0; int count = 0;
foreach (Client client in ConnectedClients) foreach (GameClient client in ConnectedClients)
{ {
if (client.LoggedIn) if (client.LoggedIn)
if (client.LoggedinUser.Administrator) if (client.LoggedinUser.Administrator)
@ -961,23 +994,25 @@ namespace Horse_Isle_Server
DroppedItems.Update(); DroppedItems.Update();
} }
} }
public static void StartServer() public static void StartServer()
{ {
ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress hostIP = IPAddress.Parse(ConfigReader.BindIP); IPAddress hostIP = IPAddress.Parse(ConfigReader.BindIP);
IPEndPoint ep = new IPEndPoint(hostIP, ConfigReader.Port); IPEndPoint ep = new IPEndPoint(hostIP, ConfigReader.Port);
ServerSocket.Bind(ep); ServerSocket.Bind(ep);
Logger.DebugPrint("Binding to ip: " + ConfigReader.BindIP + " On port: " + ConfigReader.Port.ToString()); Logger.InfoPrint("Binding to ip: " + ConfigReader.BindIP + " On port: " + ConfigReader.Port.ToString());
ServerSocket.Listen(10000); ServerSocket.Listen(10000);
serverTimer = new Timer(new TimerCallback(onTick), null, gameTickSpeed, gameTickSpeed); serverTimer = new Timer(new TimerCallback(onTick), null, gameTickSpeed, gameTickSpeed);
while (true) while (true)
{ {
Logger.DebugPrint("Waiting for new connections..."); Logger.InfoPrint("Waiting for new connections...");
Socket cientSocket = ServerSocket.Accept(); Socket cientSocket = ServerSocket.Accept();
Client client = new Client(cientSocket); GameClient client = new GameClient(cientSocket);
connectedClients.Add(client); connectedClients.Add(client);
} }
} }

View file

@ -1,8 +1,9 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using Newtonsoft.Json; using Newtonsoft.Json;
using HISP.Game;
namespace Horse_Isle_Server namespace HISP.Server
{ {
class Gamedata class Gamedata
{ {
@ -177,7 +178,7 @@ namespace Horse_Isle_Server
{ {
effectsList[ii] = new Item.Effects(); effectsList[ii] = new Item.Effects();
effectsList[ii].EffectsWhat = gameData.item.item_list[i].effects[ii].effect_what; effectsList[ii].EffectsWhat = gameData.item.item_list[i].effects[ii].effect_what;
effectsList[ii].EffectsWhat = gameData.item.item_list[i].effects[ii].effect_amount; effectsList[ii].EffectAmount = gameData.item.item_list[i].effects[ii].effect_amount;
} }
item.Effects = effectsList; item.Effects = effectsList;
@ -268,6 +269,79 @@ namespace Horse_Isle_Server
Npc.NpcList.Add(npcEntry); Npc.NpcList.Add(npcEntry);
} }
// Register Quests
Logger.DebugPrint("Registering Quests: ");
int totalQuests = gameData.quest_list.Count;
for(int i = 0; i < totalQuests; i++)
{
Quest.QuestEntry quest = new Quest.QuestEntry();
quest.Id = gameData.quest_list[i].id;
quest.Notes = gameData.quest_list[i].notes;
if(gameData.quest_list[i].title != null)
quest.Title = gameData.quest_list[i].title;
quest.RequiresQuestIdComplete = gameData.quest_list[i].requires_questid_npc.ToObject<int[]>();
if (gameData.quest_list[i].alt_activation != null)
{
quest.AltActivation = new Quest.QuestAltActivation();
quest.AltActivation.Type = gameData.quest_list[i].alt_activation.type;
quest.AltActivation.ActivateX = gameData.quest_list[i].alt_activation.x;
quest.AltActivation.ActivateY = gameData.quest_list[i].alt_activation.y;
}
quest.Tracked = gameData.quest_list[i].tracked;
quest.MaxRepeats = gameData.quest_list[i].max_repeats;
quest.MoneyCost = gameData.quest_list[i].money_cost;
int itemsRequiredCount = gameData.quest_list[i].items_required.Count;
List<Quest.QuestItemInfo> itmInfo = new List<Quest.QuestItemInfo>();
for(int ii = 0; ii < itemsRequiredCount; ii++)
{
Quest.QuestItemInfo itemInfo = new Quest.QuestItemInfo();
itemInfo.ItemId = gameData.quest_list[i].items_required[ii].item_id;
itemInfo.Quantity = gameData.quest_list[i].items_required[ii].quantity;
itmInfo.Add(itemInfo);
}
quest.ItemsRequired = itmInfo.ToArray();
if(gameData.quest_list[i].fail_npc_chat != null)
quest.FailNpcChat = gameData.quest_list[i].fail_npc_chat;
quest.MoneyEarned = gameData.quest_list[i].money_gained;
int itemsGainedCount = gameData.quest_list[i].items_gained.Count;
itmInfo = new List<Quest.QuestItemInfo>();
for (int ii = 0; ii < itemsGainedCount; ii++)
{
Quest.QuestItemInfo itemInfo = new Quest.QuestItemInfo();
itemInfo.ItemId = gameData.quest_list[i].items_gained[ii].item_id;
itemInfo.Quantity = gameData.quest_list[i].items_gained[ii].quantity;
itmInfo.Add(itemInfo);
}
quest.ItemsEarned = itmInfo.ToArray();
quest.QuestPointsEarned = gameData.quest_list[i].quest_points;
quest.GotoNpcChatpoint = gameData.quest_list[i].goto_npc_chatpoint;
if(gameData.quest_list[i].warp_x != null)
quest.WarpX = gameData.quest_list[i].warp_x;
if(gameData.quest_list[i].warp_y != null)
quest.WarpY = gameData.quest_list[i].warp_y;
if(gameData.quest_list[i].success_message != null)
quest.SuccessMessage = gameData.quest_list[i].success_message;
if(gameData.quest_list[i].success_npc_chat != null)
quest.SuccessNpcChat = gameData.quest_list[i].success_npc_chat;
if (gameData.quest_list[i].requires_awardid != null)
quest.AwardRequired = gameData.quest_list[i].requires_awardid;
quest.RequiresQuestIdCompleted = gameData.quest_list[i].requires_questid_completed.ToObject<int[]>();
quest.RequiresQuestIdNotCompleted = gameData.quest_list[i].requires_questid_not_completed.ToObject<int[]>();
quest.HideReplyOnFail = gameData.quest_list[i].hide_reply_on_fail;
if (gameData.quest_list[i].difficulty != null)
quest.Difficulty = gameData.quest_list[i].difficulty;
if (gameData.quest_list[i].author != null)
quest.Author = gameData.quest_list[i].author;
if (gameData.quest_list[i].chained_questid != null)
quest.ChainedQuestId = gameData.quest_list[i].chained_questid;
quest.Minigame = gameData.quest_list[i].minigame;
Logger.DebugPrint("Registered Quest: " + quest.Id);
Quest.QuestList.Add(quest);
}
Item.Present = gameData.item.special.present; Item.Present = gameData.item.special.present;
Item.MailMessage = gameData.item.special.mail_message; Item.MailMessage = gameData.item.special.mail_message;
Item.DorothyShoes = gameData.item.special.dorothy_shoes; Item.DorothyShoes = gameData.item.special.dorothy_shoes;
@ -331,6 +405,13 @@ namespace Horse_Isle_Server
Messages.GrabItemFormat = gameData.messages.meta.dropped_items.item_format; Messages.GrabItemFormat = gameData.messages.meta.dropped_items.item_format;
Messages.GrabAllItemsButton = gameData.messages.meta.dropped_items.grab_all; Messages.GrabAllItemsButton = gameData.messages.meta.dropped_items.grab_all;
Messages.DroppedAnItemMessage = gameData.messages.dropped_item_message; Messages.DroppedAnItemMessage = gameData.messages.dropped_item_message;
Messages.GrabbedAllObjectsMessage = gameData.messages.grab_all_message;
// Tools
Messages.BinocularsNothing = gameData.messages.tools.binoculars;
Messages.MagnifyNothing = gameData.messages.tools.magnify;
Messages.RakeNothing = gameData.messages.tools.rake;
Messages.ShovelNothing = gameData.messages.tools.shovel;
// Meta Format // Meta Format
@ -372,6 +453,8 @@ namespace Horse_Isle_Server
Messages.NpcStartChatFormat = gameData.messages.npc.start_chat_format; Messages.NpcStartChatFormat = gameData.messages.npc.start_chat_format;
Messages.NpcChatpointFormat = gameData.messages.npc.chatpoint_format; Messages.NpcChatpointFormat = gameData.messages.npc.chatpoint_format;
Messages.NpcReplyFormat = gameData.messages.npc.reply_format; Messages.NpcReplyFormat = gameData.messages.npc.reply_format;
Messages.NpcTalkButton = gameData.messages.npc.npc_talk_button;
Messages.NpcInformationButton = gameData.messages.npc.npc_information_button;
// Map Data // Map Data
@ -397,8 +480,8 @@ namespace Horse_Isle_Server
Chat.PrivateMessageSound = gameData.messages.chat.pm_sound; Chat.PrivateMessageSound = gameData.messages.chat.pm_sound;
Server.IdleWarning = gameData.messages.disconnect.client_timeout.warn_after; GameServer.IdleWarning = gameData.messages.disconnect.client_timeout.warn_after;
Server.IdleTimeout = gameData.messages.disconnect.client_timeout.kick_after; GameServer.IdleTimeout = gameData.messages.disconnect.client_timeout.kick_after;
// Inventory // Inventory

View file

@ -1,10 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Horse_Isle_Server namespace HISP.Server
{ {
class Logger class Logger
{ {

View file

@ -1,8 +1,8 @@
using System; using System;
using System.IO; using System.IO;
using System.Text; using System.Text;
using HISP.Game;
namespace Horse_Isle_Server namespace HISP.Server
{ {
class PacketBuilder class PacketBuilder
{ {
@ -61,6 +61,10 @@ namespace Horse_Isle_Server
public const byte ITEM_DROP = 0x1E; public const byte ITEM_DROP = 0x1E;
public const byte ITEM_PICKUP = 0x14; public const byte ITEM_PICKUP = 0x14;
public const byte ITEM_BINOCULARS = 0x5C;
public const byte ITEM_MAGNIFYING = 0x5D;
public const byte ITEM_RAKE = 0x5B;
public const byte ITEM_SHOVEL = 0x5A;
public const byte LOGIN_INVALID_USER_PASS = 0x15; public const byte LOGIN_INVALID_USER_PASS = 0x15;
public const byte LOGIN_SUCCESS = 0x14; public const byte LOGIN_SUCCESS = 0x14;