From 8ca94a1dcfabcad47d27598b515a2b2a889d6d0d Mon Sep 17 00:00:00 2001 From: LastExceed Date: Sun, 30 Sep 2018 09:20:06 +0200 Subject: [PATCH 01/13] introduce events part1 --- Server/{Addon => Extensions}/AntiCheat.cs | 47 +++++---- Server/Extensions/ChatCommands.cs | 84 +++++++++++++++ Server/Extensions/Extensions.cs | 12 +++ Server/Extensions/Pvp.cs | 19 ++++ Server/Extensions/Tombstones.cs | 45 +++++++++ Server/Server.cs | 118 ++-------------------- Server/Server_Events.cs | 28 +++++ 7 files changed, 227 insertions(+), 126 deletions(-) rename Server/{Addon => Extensions}/AntiCheat.cs (68%) create mode 100644 Server/Extensions/ChatCommands.cs create mode 100644 Server/Extensions/Extensions.cs create mode 100644 Server/Extensions/Pvp.cs create mode 100644 Server/Extensions/Tombstones.cs create mode 100644 Server/Server_Events.cs diff --git a/Server/Addon/AntiCheat.cs b/Server/Extensions/AntiCheat.cs similarity index 68% rename from Server/Addon/AntiCheat.cs rename to Server/Extensions/AntiCheat.cs index d3c707c..4684778 100644 --- a/Server/Addon/AntiCheat.cs +++ b/Server/Extensions/AntiCheat.cs @@ -1,17 +1,31 @@ using Resources; using Resources.Packet; +using System; +using System.Collections.Generic; +using System.Text; -namespace Server.Addon { - class AntiCheat { - public static string Inspect(EntityUpdate current, EntityUpdate previous) { +namespace Server.Extensions { + public static class AntiCheat { + public static void Init() { + Server.EntityUpdated += That; + } + + private static void That(EntityUpdate entityUpdate, Player player) { + string ACmessage = Inspect(entityUpdate, player.entity); + if (ACmessage != null) { + Server.Kick(player, ACmessage); + } + } + + private static string Inspect(EntityUpdate current, EntityUpdate previous) { if (current.guid != previous.guid) { return "guid"; } if (current.hostility != null && current.hostility != 0) { return "hostility"; } - if(current.appearance != null) { - if((current.appearance.character_size.x != 0.8000000119f && current.appearance.character_size.x != 0.9600000381f && current.appearance.character_size.x != 1.039999962f) || + if (current.appearance != null) { + if ((current.appearance.character_size.x != 0.8000000119f && current.appearance.character_size.x != 0.9600000381f && current.appearance.character_size.x != 1.039999962f) || (current.appearance.character_size.y != 0.8000000119f && current.appearance.character_size.y != 0.9600000381f && current.appearance.character_size.y != 1.039999962f) || (current.appearance.character_size.z != 1.799999952f && current.appearance.character_size.z != 2.160000086f && current.appearance.character_size.z != 2.339999914f) || (current.appearance.head_size != 0.8999999762f && current.appearance.head_size != 1.00999999f) || @@ -26,13 +40,13 @@ public static string Inspect(EntityUpdate current, EntityUpdate previous) { return "appearance"; } } - if(current.charge != null && current.charge > 1){ //(current.MP ?? previous.MP)) { + if (current.charge != null && current.charge > 1) { //(current.MP ?? previous.MP)) { return "MP charge"; } - if(current.HP != null && current.HP > 3333) { + if (current.HP != null && current.HP > 3333) { return "HP"; } - if(current.MP != null && current.MP > 1) { + if (current.MP != null && current.MP > 1) { return "MP"; } //if(current.multipliers != null) { @@ -44,27 +58,27 @@ public static string Inspect(EntityUpdate current, EntityUpdate previous) { // return "multipliers"; // } //} - if(current.level != null && current.level > 500) { + if (current.level != null && current.level > 500) { return "level"; } - if(current.consumable != null) { - if(current.consumable.type == ItemType.Food && + if (current.consumable != null) { + if (current.consumable.type == ItemType.Food && current.consumable.subtype == 1 || current.consumable.level > 647 || current.consumable.rarity != 0) { //return "consumable"; } } - if(current.equipment != null) { - foreach(Item item in current.equipment) { - if(item.type != 0 && + if (current.equipment != null) { + foreach (Item item in current.equipment) { + if (item.type != 0 && (item.level > 647 || (byte)item.rarity > 4)) { return "equipment"; } } } - if(current.skillDistribution != null) { - if(current.skillDistribution.petmaster + + if (current.skillDistribution != null) { + if (current.skillDistribution.petmaster + current.skillDistribution.petriding + current.skillDistribution.sailing + current.skillDistribution.climbing + @@ -82,4 +96,3 @@ public static string Inspect(EntityUpdate current, EntityUpdate previous) { } } } -//block diff --git a/Server/Extensions/ChatCommands.cs b/Server/Extensions/ChatCommands.cs new file mode 100644 index 0000000..bbaa26f --- /dev/null +++ b/Server/Extensions/ChatCommands.cs @@ -0,0 +1,84 @@ +using Resources; +using Resources.Datagram; +using Resources.Packet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Server.Extensions { + public static class ChatCommands { + public static void Init() { + Server.ChatMessageReceived += ParseAsCommand; + } + + private static void ParseAsCommand(string message, Player source) { + if (!message.StartsWith("/")) { + return; + } + var parameters = message.Substring(1).Split(" "); + var command = parameters[0].ToLower(); + switch (command) { + case "kick": + case "btfo": + case "ban": + #region ban + if (source.entity.name != "BLACKROCK") { + Server.Notify(source, "no permission"); + break; + } + if (parameters.Length == 1) { + Server.Notify(source, string.Format("usage example: /kick blackrock")); + break; + } + var target = Server.players.FirstOrDefault(x => x.entity.name.Contains(parameters[1])); + if (target == null) { + Server.Notify(source, "invalid target"); + break; + }; + var reason = "no reason specified"; + if (parameters.Length > 2) { + reason = parameters[2]; + } + if (command == "kick") { + Server.Kick(target, reason); + break; + } + target.writer.Write((byte)ServerPacketID.BTFO); + target.writer.Write(reason); + if (command == "ban") { + Server.Database.BanUser(target.entity.name, (int)target.IP.Address, target.MAC, reason); + } + Server.RemovePlayerEntity(target, false); + break; + #endregion + case "bleeding": + + break; + case "time": + #region time + if (parameters.Length == 1) { + Server.Notify(source, string.Format("usage example: /time 12:00")); + break; + } + var clock = parameters[1].Split(":"); + if (clock.Length < 2 || + !int.TryParse(clock[0], out int hour) || + !int.TryParse(clock[1], out int minute)) { + Server.Notify(source, string.Format("invalid syntax")); + break; + } + var inGameTime = new InGameTime() { + Milliseconds = (hour * 60 + minute) * 60000, + }; + Server.SendUDP(inGameTime.data, source); + break; + #endregion + default: + Server.Notify(source, string.Format("unknown command '{0}'", parameters[0])); + break; + } + break; + } + } +} diff --git a/Server/Extensions/Extensions.cs b/Server/Extensions/Extensions.cs new file mode 100644 index 0000000..c15b1be --- /dev/null +++ b/Server/Extensions/Extensions.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Server.Extensions { + public static class Extensions { + public static void Init() { + AntiCheat.Init(); + Pvp.Init(); + } + } +} diff --git a/Server/Extensions/Pvp.cs b/Server/Extensions/Pvp.cs new file mode 100644 index 0000000..77f7440 --- /dev/null +++ b/Server/Extensions/Pvp.cs @@ -0,0 +1,19 @@ +using Resources; +using Resources.Packet; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Server.Extensions { + public static class Pvp { + public static void Init() { + Server.EntityUpdated += EnableFriendlyFireFlag; + } + + private static void EnableFriendlyFireFlag(EntityUpdate entityUpdate, Player player) { + entityUpdate.entityFlags |= 1 << 5; + + + } + } +} diff --git a/Server/Extensions/Tombstones.cs b/Server/Extensions/Tombstones.cs new file mode 100644 index 0000000..6b6d664 --- /dev/null +++ b/Server/Extensions/Tombstones.cs @@ -0,0 +1,45 @@ +using Resources; +using Resources.Datagram; +using Resources.Packet; +using Resources.Utilities; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Server.Extensions { + public static class Tombstones { + public static void Init() { + Server.EntityUpdated += SpawnTomb; + } + + private static void SpawnTomb(EntityUpdate entityUpdate, Player player) { + if (entityUpdate.HP <= 0 && (player.entity.HP > 0 || player.entity.HP == null)) { + var tombstone = new EntityUpdate() { + guid = Server.AssignGuid(), + position = entityUpdate.position ?? player.entity.position, + hostility = Hostility.Neutral, + entityType = EntityType.None, + appearance = new EntityUpdate.Appearance() { + character_size = new FloatVector() { + x = 1, + y = 1, + z = 1, + }, + head_model = 2155, + head_size = 1 + }, + HP = 100, + name = "tombstone" + }; + player.tomb = (ushort)tombstone.guid; + Server.BroadcastUDP(tombstone.CreateDatagram()); + } + else if (player.entity.HP <= 0 && entityUpdate.HP > 0 && player.tomb != null) { + var rde = new RemoveDynamicEntity() { + Guid = (ushort)player.tomb, + }; + Server.BroadcastUDP(rde.data); + } + } + } +} diff --git a/Server/Server.cs b/Server/Server.cs index 92772fa..168fc37 100644 --- a/Server/Server.cs +++ b/Server/Server.cs @@ -17,7 +17,7 @@ using Resources.Utilities; namespace Server { - public static class Server { + public static partial class Server { public static UdpClient udpClient; public static TcpListener tcpListener; public static List players = new List(); @@ -242,47 +242,7 @@ private static void ProcessDatagram(byte[] datagram, Player source) { case DatagramID.DynamicUpdate: #region entityUpdate var entityUpdate = new EntityUpdate(datagram); - #region antiCheat - string ACmessage = AntiCheat.Inspect(entityUpdate, source.entity); - if (ACmessage != null) Kick(source, ACmessage); - #endregion - #region announce - if (entityUpdate.name != null) { - //Announce.Join(entityUpdate.name, player.entityData.name, players); - } - #endregion - #region pvp - entityUpdate.entityFlags |= 1 << 5; //enable friendly fire flag for pvp - #endregion - #region tombstone - if (entityUpdate.HP <= 0 && (source.entity.HP > 0 || source.entity.HP == null)) { - var tombstone = new EntityUpdate() { - guid = AssignGuid(), - position = entityUpdate.position ?? source.entity.position, - hostility = Hostility.Neutral, - entityType = EntityType.None, - appearance = new EntityUpdate.Appearance() { - character_size = new FloatVector() { - x = 1, - y = 1, - z = 1, - }, - head_model = 2155, - head_size = 1 - }, - HP = 100, - name = "tombstone" - }; - source.tomb = (ushort)tombstone.guid; - BroadcastUDP(tombstone.CreateDatagram()); - } - else if (source.entity.HP <= 0 && entityUpdate.HP > 0 && source.tomb != null) { - var rde = new RemoveDynamicEntity() { - Guid = (ushort)source.tomb, - }; - BroadcastUDP(rde.data); - } - #endregion + EntityUpdated(entityUpdate, source); entityUpdate.Merge(source.entity); BroadcastUDP(entityUpdate.CreateDatagram(), source); break; @@ -290,6 +250,7 @@ private static void ProcessDatagram(byte[] datagram, Player source) { case DatagramID.Attack: #region attack var attack = new Attack(datagram); + EntityAttacked(attack, source); source.lastTarget = attack.Target; var target = players.FirstOrDefault(p => p.entity?.guid == attack.Target); if (target != null) SendUDP(attack.data, target); @@ -298,105 +259,44 @@ private static void ProcessDatagram(byte[] datagram, Player source) { case DatagramID.Projectile: #region Projectile var projectile = new Projectile(datagram); + ProjectileCreated(projectile, source); BroadcastUDP(projectile.data, source); //pass to all players except source break; #endregion case DatagramID.Proc: #region proc var proc = new Proc(datagram); + PassiveProcced(proc, source); BroadcastUDP(proc.data, source); //pass to all players except source break; #endregion case DatagramID.Chat: #region chat var chat = new Chat(datagram); - - if (chat.Text.StartsWith("/")) { - var parameters = chat.Text.Substring(1).Split(" "); - var command = parameters[0].ToLower(); - switch (command) { - case "kick": - case "btfo": - case "ban": - #region ban - if (source.entity.name != "BLACKROCK") { - Notify(source, "no permission"); - break; - } - if (parameters.Length == 1) { - Notify(source, string.Format("usage example: /kick blackrock")); - break; - } - target = players.FirstOrDefault(x => x.entity.name.Contains(parameters[1])); - if (target == null) { - Notify(source, "invalid target"); - break; - }; - var reason = "no reason specified"; - if (parameters.Length > 2) { - reason = parameters[2]; - } - if (command == "kick") { - Kick(target, reason); - break; - } - target.writer.Write((byte)ServerPacketID.BTFO); - target.writer.Write(reason); - if (command == "ban") { - Database.BanUser(target.entity.name, (int)target.IP.Address, target.MAC, reason); - } - RemovePlayerEntity(target, false); - break; - #endregion - case "bleeding": - - break; - case "time": - #region time - if (parameters.Length == 1) { - Notify(source, string.Format("usage example: /time 12:00")); - break; - } - var clock = parameters[1].Split(":"); - if (clock.Length < 2 || - !int.TryParse(clock[0], out int hour) || - !int.TryParse(clock[1], out int minute)) { - Notify(source, string.Format("invalid syntax")); - break; - } - var inGameTime = new InGameTime() { - Milliseconds = (hour * 60 + minute) * 60000, - }; - SendUDP(inGameTime.data, source); - break; - #endregion - default: - Notify(source, string.Format("unknown command '{0}'", parameters[0])); - break; - } - break; - } + ChatMessageReceived(chat.Text, source); Log.Print(dynamicEntities[chat.Sender].name + ": ", ConsoleColor.Cyan); Log.PrintLn(chat.Text, ConsoleColor.White, false); - BroadcastUDP(chat.data, null); //pass to all players break; #endregion case DatagramID.Interaction: #region interaction var interaction = new Interaction(datagram); + EntityInteracted(interaction, source); BroadcastUDP(interaction.data, source); //pass to all players except source break; #endregion case DatagramID.RemoveDynamicEntity: #region removeDynamicEntity var remove = new RemoveDynamicEntity(datagram); + EntityRemoved(remove, source); RemovePlayerEntity(source, true); break; #endregion case DatagramID.SpecialMove: #region specialMove var specialMove = new SpecialMove(datagram); + SpecialMoveUsed(specialMove, source); switch (specialMove.Id) { case SpecialMoveID.Taunt: target = players.FirstOrDefault(p => p.entity.guid == specialMove.Guid); diff --git a/Server/Server_Events.cs b/Server/Server_Events.cs new file mode 100644 index 0000000..e474318 --- /dev/null +++ b/Server/Server_Events.cs @@ -0,0 +1,28 @@ +using Resources; +using Resources.Datagram; +using Resources.Packet; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Server { + public delegate void EntityUpdatedEventHandler(EntityUpdate entityUpdate, Player source); + public delegate void EntityAttackedEventHandler(Attack datagram, Player source); + public delegate void ProjectileCreatedEventHandler(Projectile datagram, Player source); + public delegate void PassiveProccedEventHandler(Proc datagram, Player source); + public delegate void ChatMessageReceivedEventHandler(string message, Player source); + public delegate void EntityInteractedEventHandler(Interaction datagram, Player source); + public delegate void EntityRemovedEventHandler(RemoveDynamicEntity datagram, Player source); + public delegate void SpecialMoveUsedEventHandler(SpecialMove datagram, Player source); + + public static partial class Server { + public static event EntityUpdatedEventHandler EntityUpdated; + public static event EntityAttackedEventHandler EntityAttacked; + public static event ProjectileCreatedEventHandler ProjectileCreated; + public static event PassiveProccedEventHandler PassiveProcced; + public static event ChatMessageReceivedEventHandler ChatMessageReceived; + public static event EntityInteractedEventHandler EntityInteracted; + public static event EntityRemovedEventHandler EntityRemoved; + public static event SpecialMoveUsedEventHandler SpecialMoveUsed; + } +} From 38f8eeb84dc24987c7d41aff429d0ccdcb34cdb3 Mon Sep 17 00:00:00 2001 From: LastExceed Date: Sun, 30 Sep 2018 10:42:23 +0200 Subject: [PATCH 02/13] introduce events part2 --- Server/Extensions/ChatCommands.cs | 3 +- Server/Extensions/Extensions.cs | 2 + Server/Extensions/Models.cs | 83 +++++++++++++++++++++++ Server/Extensions/SpecialMoves.cs | 40 +++++++++++ Server/Server.cs | 106 ++---------------------------- 5 files changed, 133 insertions(+), 101 deletions(-) create mode 100644 Server/Extensions/Models.cs create mode 100644 Server/Extensions/SpecialMoves.cs diff --git a/Server/Extensions/ChatCommands.cs b/Server/Extensions/ChatCommands.cs index bbaa26f..65adc21 100644 --- a/Server/Extensions/ChatCommands.cs +++ b/Server/Extensions/ChatCommands.cs @@ -47,7 +47,7 @@ private static void ParseAsCommand(string message, Player source) { target.writer.Write((byte)ServerPacketID.BTFO); target.writer.Write(reason); if (command == "ban") { - Server.Database.BanUser(target.entity.name, (int)target.IP.Address, target.MAC, reason); + Server.userDatabase.BanUser(target.entity.name, (int)target.IP.Address, target.MAC, reason); } Server.RemovePlayerEntity(target, false); break; @@ -78,7 +78,6 @@ private static void ParseAsCommand(string message, Player source) { Server.Notify(source, string.Format("unknown command '{0}'", parameters[0])); break; } - break; } } } diff --git a/Server/Extensions/Extensions.cs b/Server/Extensions/Extensions.cs index c15b1be..f15bad9 100644 --- a/Server/Extensions/Extensions.cs +++ b/Server/Extensions/Extensions.cs @@ -7,6 +7,8 @@ public static class Extensions { public static void Init() { AntiCheat.Init(); Pvp.Init(); + ChatCommands.Init(); + SpecialMoves.Init(); } } } diff --git a/Server/Extensions/Models.cs b/Server/Extensions/Models.cs new file mode 100644 index 0000000..51e9357 --- /dev/null +++ b/Server/Extensions/Models.cs @@ -0,0 +1,83 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Server.Extensions { + public static class Models { + public static void Init() { + + } + + private static void Placeholder() { + #region models + //var rnd = new Random(); + //for (int i = 8286946; i < 8286946 + 512; i++) { + // for (int j = 8344456; j < 8344456 + 512; j++) { + // var block = new ServerUpdate.BlockDelta() { + // color = new Resources.Utilities.ByteVector() { + // x = 0, + // y = 0, + // z = (byte)rnd.Next(0, 255), + // }, + // type = BlockType.solid, + // position = new Resources.Utilities.IntVector() { + // x = i, + // y = j, + // z = 208, + // }, + // }; + // worldUpdate.blockDeltas.Add(block); + // } + //} + //x = 543093329157, + //y = 546862296355, + //z = 14423162 + //ZoxModel model = JsonConvert.DeserializeObject(File.ReadAllText("models/Fulcnix_exceedspawn.zox")); + //model.Parse(worldUpdate, 8286883, 8344394, 200); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_Tavern2.zox")); + //model.Parse(worldUpdate, 8287010, 8344432, 200); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_Tavern1.zox")); + //model.Parse(worldUpdate, 8286919, 8344315, 212); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/arena/aster_arena.zox")); + //model.Parse(worldUpdate, 8286775, 8344392, 207); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/michael_project1.zox")); + //model.Parse(worldUpdate, 8286898, 8344375, 213); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/arena/fulcnix_hall.zox")); + //model.Parse(worldUpdate, 8286885, 8344505, 208); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/arena/fulcnix_hall.zox")); + //model.Parse(worldUpdate, 8286885, 8344629, 208); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Tiecz_MountainArena.zox")); + //model.Parse(worldUpdate, 8286885, 8344759, 208); + ////8397006, 8396937, 127 //near spawn + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay11.zox")); + //model.Parse(worldUpdate, 8286770, 8344262, 207); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay12.zox")); + //model.Parse(worldUpdate, 8286770, 8344136, 207); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay13.zox")); + //model.Parse(worldUpdate, 8286770, 8344010, 207); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay14.zox")); + //model.Parse(worldUpdate, 8286770, 8344010, 333); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay01.zox")); + //model.Parse(worldUpdate, 8286644, 8344010, 333); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay02.zox")); + //model.Parse(worldUpdate, 8286118, 8344010, 333); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay03.zox")); + //model.Parse(worldUpdate, 8285992, 8344010, 333); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay04.zox")); + //model.Parse(worldUpdate, 8285992, 8344136, 333); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay05.zox")); + //model.Parse(worldUpdate, 8285992, 8344262, 333); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay06.zox")); + //model.Parse(worldUpdate, 8286118, 8344262, 333); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay07.zox")); + //model.Parse(worldUpdate, 8286118, 8344136, 333); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay08.zox")); + //model.Parse(worldUpdate, 8286244, 8344136, 333); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay09.zox")); + //model.Parse(worldUpdate, 8286244, 8344262, 333); + //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay10.zox")); + //model.Parse(worldUpdate, 8286770, 8344262, 333); + #endregion + } + } +} diff --git a/Server/Extensions/SpecialMoves.cs b/Server/Extensions/SpecialMoves.cs new file mode 100644 index 0000000..f12481c --- /dev/null +++ b/Server/Extensions/SpecialMoves.cs @@ -0,0 +1,40 @@ +using Resources; +using Resources.Datagram; +using Resources.Packet; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Server.Extensions { + public static class SpecialMoves { + public static void Init() { + Server.SpecialMoveUsed += OnSpecialMove; + } + + private static void OnSpecialMove(SpecialMove specialMove, Player source) { + switch (specialMove.Id) { + case SpecialMoveID.Taunt: + var target = Server.players.FirstOrDefault(p => p.entity.guid == specialMove.Guid); + if (target != null) { + specialMove.Guid = (ushort)source.entity.guid; + Server.SendUDP(specialMove.data, target); + } + break; + case SpecialMoveID.SmokeBomb: + Server.BroadcastUDP(specialMove.data, source); + break; + case SpecialMoveID.CursedArrow: + case SpecialMoveID.ArrowRain: + case SpecialMoveID.Shrapnel: + case SpecialMoveID.IceWave: + case SpecialMoveID.Confusion: + case SpecialMoveID.ShadowStep: + Server.BroadcastUDP(specialMove.data); + break; + default: + break; + } + } + } +} diff --git a/Server/Server.cs b/Server/Server.cs index 168fc37..91e275a 100644 --- a/Server/Server.cs +++ b/Server/Server.cs @@ -22,82 +22,12 @@ public static partial class Server { public static TcpListener tcpListener; public static List players = new List(); public static Dictionary dynamicEntities = new Dictionary(); - public static UserDatabase Database; + public static UserDatabase userDatabase; public static void Start(int port) { Log.PrintLn("server starting..."); - Database = new UserDatabase(); - Database.Database.Migrate(); //Ensure database exists - - #region models - //var rnd = new Random(); - //for (int i = 8286946; i < 8286946 + 512; i++) { - // for (int j = 8344456; j < 8344456 + 512; j++) { - // var block = new ServerUpdate.BlockDelta() { - // color = new Resources.Utilities.ByteVector() { - // x = 0, - // y = 0, - // z = (byte)rnd.Next(0, 255), - // }, - // type = BlockType.solid, - // position = new Resources.Utilities.IntVector() { - // x = i, - // y = j, - // z = 208, - // }, - // }; - // worldUpdate.blockDeltas.Add(block); - // } - //} - //x = 543093329157, - //y = 546862296355, - //z = 14423162 - //ZoxModel model = JsonConvert.DeserializeObject(File.ReadAllText("models/Fulcnix_exceedspawn.zox")); - //model.Parse(worldUpdate, 8286883, 8344394, 200); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_Tavern2.zox")); - //model.Parse(worldUpdate, 8287010, 8344432, 200); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_Tavern1.zox")); - //model.Parse(worldUpdate, 8286919, 8344315, 212); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/arena/aster_arena.zox")); - //model.Parse(worldUpdate, 8286775, 8344392, 207); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/michael_project1.zox")); - //model.Parse(worldUpdate, 8286898, 8344375, 213); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/arena/fulcnix_hall.zox")); - //model.Parse(worldUpdate, 8286885, 8344505, 208); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/arena/fulcnix_hall.zox")); - //model.Parse(worldUpdate, 8286885, 8344629, 208); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Tiecz_MountainArena.zox")); - //model.Parse(worldUpdate, 8286885, 8344759, 208); - ////8397006, 8396937, 127 //near spawn - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay11.zox")); - //model.Parse(worldUpdate, 8286770, 8344262, 207); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay12.zox")); - //model.Parse(worldUpdate, 8286770, 8344136, 207); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay13.zox")); - //model.Parse(worldUpdate, 8286770, 8344010, 207); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay14.zox")); - //model.Parse(worldUpdate, 8286770, 8344010, 333); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay01.zox")); - //model.Parse(worldUpdate, 8286644, 8344010, 333); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay02.zox")); - //model.Parse(worldUpdate, 8286118, 8344010, 333); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay03.zox")); - //model.Parse(worldUpdate, 8285992, 8344010, 333); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay04.zox")); - //model.Parse(worldUpdate, 8285992, 8344136, 333); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay05.zox")); - //model.Parse(worldUpdate, 8285992, 8344262, 333); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay06.zox")); - //model.Parse(worldUpdate, 8286118, 8344262, 333); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay07.zox")); - //model.Parse(worldUpdate, 8286118, 8344136, 333); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay08.zox")); - //model.Parse(worldUpdate, 8286244, 8344136, 333); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay09.zox")); - //model.Parse(worldUpdate, 8286244, 8344262, 333); - //model = JsonConvert.DeserializeObject(File.ReadAllText("models/Aster_CloudyDay10.zox")); - //model.Parse(worldUpdate, 8286770, 8344262, 333); - #endregion + userDatabase = new UserDatabase(); + userDatabase.Database.Migrate(); //Ensure database exists udpClient = new UdpClient(new IPEndPoint(IPAddress.Any, port)); new Thread(new ThreadStart(ListenUDP)).Start(); @@ -138,10 +68,10 @@ private static void ListenUDP() { } } - private static void SendUDP(byte[] data, Player target) { + public static void SendUDP(byte[] data, Player target) { udpClient.Send(data, data.Length, target.RemoteEndPoint); } - private static void BroadcastUDP(byte[] data, Player toSkip = null) { + public static void BroadcastUDP(byte[] data, Player toSkip = null) { foreach (var player in players) { if (player != toSkip) { SendUDP(data, player); @@ -186,7 +116,7 @@ private static void ProcessPacket(byte packetID, Player source) { authResponse = AuthResponse.AccountAlreadyActive; } else { - authResponse = Database.AuthUser(username, password, (int)source.IP.Address, source.MAC); + authResponse = userDatabase.AuthUser(username, password, (int)source.IP.Address, source.MAC); } source.writer.Write((byte)ServerPacketID.Login); source.writer.Write((byte)authResponse); @@ -222,7 +152,7 @@ private static void ProcessPacket(byte packetID, Player source) { registerResponse = RegisterResponse.InvalidInput; } else { - registerResponse = Database.RegisterUser(username, email, password); + registerResponse = userDatabase.RegisterUser(username, email, password); } source.writer.Write((byte)ServerPacketID.Register); source.writer.Write((byte)registerResponse); @@ -297,28 +227,6 @@ private static void ProcessDatagram(byte[] datagram, Player source) { #region specialMove var specialMove = new SpecialMove(datagram); SpecialMoveUsed(specialMove, source); - switch (specialMove.Id) { - case SpecialMoveID.Taunt: - target = players.FirstOrDefault(p => p.entity.guid == specialMove.Guid); - if (target != null) { - specialMove.Guid = (ushort)source.entity.guid; - SendUDP(specialMove.data, target); - } - break; - case SpecialMoveID.SmokeBomb: - BroadcastUDP(specialMove.data, source); - break; - case SpecialMoveID.CursedArrow: - case SpecialMoveID.ArrowRain: - case SpecialMoveID.Shrapnel: - case SpecialMoveID.IceWave: - case SpecialMoveID.Confusion: - case SpecialMoveID.ShadowStep: - BroadcastUDP(specialMove.data); - break; - default: - break; - } break; #endregion case DatagramID.HolePunch: From bfd71e29894854e12182c0f42293b4f7135efd90 Mon Sep 17 00:00:00 2001 From: LastExceed Date: Fri, 12 Oct 2018 23:35:20 +0200 Subject: [PATCH 03/13] add extensions intialization --- Server/Server.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Server/Server.cs b/Server/Server.cs index 91e275a..e0f4e35 100644 --- a/Server/Server.cs +++ b/Server/Server.cs @@ -34,6 +34,8 @@ public static void Start(int port) { tcpListener = new TcpListener(IPAddress.Any, port); tcpListener.Start(); new Thread(new ThreadStart(ListenTCP)).Start(); + + Extensions.Extensions.Init(); Log.PrintLn("loading completed"); } From 7a7c3a3966ccdc2dd63ccbfe9a918ebd155621ac Mon Sep 17 00:00:00 2001 From: LastExceed Date: Sat, 13 Oct 2018 00:30:17 +0200 Subject: [PATCH 04/13] check if eventhandlers are null before raising them --- Server/Server.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Server/Server.cs b/Server/Server.cs index e0f4e35..84b8a94 100644 --- a/Server/Server.cs +++ b/Server/Server.cs @@ -174,7 +174,7 @@ private static void ProcessDatagram(byte[] datagram, Player source) { case DatagramID.DynamicUpdate: #region entityUpdate var entityUpdate = new EntityUpdate(datagram); - EntityUpdated(entityUpdate, source); + EntityUpdated?.Invoke(entityUpdate, source); entityUpdate.Merge(source.entity); BroadcastUDP(entityUpdate.CreateDatagram(), source); break; @@ -182,7 +182,7 @@ private static void ProcessDatagram(byte[] datagram, Player source) { case DatagramID.Attack: #region attack var attack = new Attack(datagram); - EntityAttacked(attack, source); + EntityAttacked?.Invoke(attack, source); source.lastTarget = attack.Target; var target = players.FirstOrDefault(p => p.entity?.guid == attack.Target); if (target != null) SendUDP(attack.data, target); @@ -191,21 +191,21 @@ private static void ProcessDatagram(byte[] datagram, Player source) { case DatagramID.Projectile: #region Projectile var projectile = new Projectile(datagram); - ProjectileCreated(projectile, source); + ProjectileCreated?.Invoke(projectile, source); BroadcastUDP(projectile.data, source); //pass to all players except source break; #endregion case DatagramID.Proc: #region proc var proc = new Proc(datagram); - PassiveProcced(proc, source); + PassiveProcced?.Invoke(proc, source); BroadcastUDP(proc.data, source); //pass to all players except source break; #endregion case DatagramID.Chat: #region chat var chat = new Chat(datagram); - ChatMessageReceived(chat.Text, source); + ChatMessageReceived?.Invoke(chat.Text, source); Log.Print(dynamicEntities[chat.Sender].name + ": ", ConsoleColor.Cyan); Log.PrintLn(chat.Text, ConsoleColor.White, false); BroadcastUDP(chat.data, null); //pass to all players @@ -214,21 +214,21 @@ private static void ProcessDatagram(byte[] datagram, Player source) { case DatagramID.Interaction: #region interaction var interaction = new Interaction(datagram); - EntityInteracted(interaction, source); + EntityInteracted?.Invoke(interaction, source); BroadcastUDP(interaction.data, source); //pass to all players except source break; #endregion case DatagramID.RemoveDynamicEntity: #region removeDynamicEntity var remove = new RemoveDynamicEntity(datagram); - EntityRemoved(remove, source); + EntityRemoved?.Invoke(remove, source); RemovePlayerEntity(source, true); break; #endregion case DatagramID.SpecialMove: #region specialMove var specialMove = new SpecialMove(datagram); - SpecialMoveUsed(specialMove, source); + SpecialMoveUsed?.Invoke(specialMove, source); break; #endregion case DatagramID.HolePunch: From c79b6e1708287970e66652efa43035e75467d78e Mon Sep 17 00:00:00 2001 From: LastExceed Date: Sat, 13 Oct 2018 01:34:00 +0200 Subject: [PATCH 05/13] add damage reduction --- Server/Extensions/Balancing.cs | 19 +++++++++++++++++++ Server/Extensions/Extensions.cs | 1 + Server/Extensions/Pvp.cs | 2 -- 3 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 Server/Extensions/Balancing.cs diff --git a/Server/Extensions/Balancing.cs b/Server/Extensions/Balancing.cs new file mode 100644 index 0000000..629a215 --- /dev/null +++ b/Server/Extensions/Balancing.cs @@ -0,0 +1,19 @@ +using Resources; +using Resources.Datagram; + +namespace Server.Extensions { + public static class Balancing { + public static void Init() { + Server.EntityAttacked += CutDmgInHalf; + } + + private static void CutDmgInHalf(Attack datagram, Player player) { + if (datagram.Damage < 0) { + datagram.Damage *= 0.5f; //dmg + } + else { + datagram.Damage *= 0.333333f; //heal + } + } + } +} diff --git a/Server/Extensions/Extensions.cs b/Server/Extensions/Extensions.cs index f15bad9..c14a3c6 100644 --- a/Server/Extensions/Extensions.cs +++ b/Server/Extensions/Extensions.cs @@ -9,6 +9,7 @@ public static void Init() { Pvp.Init(); ChatCommands.Init(); SpecialMoves.Init(); + Balancing.Init(); } } } diff --git a/Server/Extensions/Pvp.cs b/Server/Extensions/Pvp.cs index 77f7440..94cb147 100644 --- a/Server/Extensions/Pvp.cs +++ b/Server/Extensions/Pvp.cs @@ -12,8 +12,6 @@ public static void Init() { private static void EnableFriendlyFireFlag(EntityUpdate entityUpdate, Player player) { entityUpdate.entityFlags |= 1 << 5; - - } } } From a6ece99eecd7a448aeea01b7b23eafc7b04e110f Mon Sep 17 00:00:00 2001 From: LastExceed Date: Sat, 13 Oct 2018 01:53:39 +0200 Subject: [PATCH 06/13] switch heal and dmg reduction multipliers --- Server/Extensions/Balancing.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Server/Extensions/Balancing.cs b/Server/Extensions/Balancing.cs index 629a215..f8800a5 100644 --- a/Server/Extensions/Balancing.cs +++ b/Server/Extensions/Balancing.cs @@ -7,12 +7,12 @@ public static void Init() { Server.EntityAttacked += CutDmgInHalf; } - private static void CutDmgInHalf(Attack datagram, Player player) { - if (datagram.Damage < 0) { - datagram.Damage *= 0.5f; //dmg + private static void CutDmgInHalf(Attack attack, Player player) { + if (attack.Damage > 0) { + attack.Damage *= 0.5f; //dmg } else { - datagram.Damage *= 0.333333f; //heal + attack.Damage *= 0.333333f; //heal } } } From 2762492a67b377604877fcb2a18bc7ffdb9ae9f8 Mon Sep 17 00:00:00 2001 From: LastExceed Date: Sat, 13 Oct 2018 02:19:22 +0200 Subject: [PATCH 07/13] switch heal and dmg reduction multipliers --- Server/Extensions/Balancing.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Server/Extensions/Balancing.cs b/Server/Extensions/Balancing.cs index f8800a5..f196d78 100644 --- a/Server/Extensions/Balancing.cs +++ b/Server/Extensions/Balancing.cs @@ -14,6 +14,9 @@ private static void CutDmgInHalf(Attack attack, Player player) { else { attack.Damage *= 0.333333f; //heal } + if (attack.Target == player.entity.guid) {//players can't damage themselves. this prevents double self heals since selfheal is already applied locally + attack.Damage = 0; + } } } } From 8916fdcf32770478057c27af18431656df6f996d Mon Sep 17 00:00:00 2001 From: LastExceed Date: Sun, 14 Oct 2018 14:29:06 +0200 Subject: [PATCH 08/13] add dmgReductionByShield --- Server/Extensions/Balancing.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Server/Extensions/Balancing.cs b/Server/Extensions/Balancing.cs index f196d78..f70ee1d 100644 --- a/Server/Extensions/Balancing.cs +++ b/Server/Extensions/Balancing.cs @@ -11,9 +11,21 @@ private static void CutDmgInHalf(Attack attack, Player player) { if (attack.Damage > 0) { attack.Damage *= 0.5f; //dmg } - else { - attack.Damage *= 0.333333f; //heal + //else { + // attack.Damage *= 0.333333f; //heal + //} + var target = Server.dynamicEntities[attack.Target]; + var dmgReductionByShield = 0f; + if (target.equipment[(int)Equipment.LeftWeapon].subtype == (byte)ItemSubtypeWeapon.Shield) { + dmgReductionByShield += 0.25f; } + if (target.equipment[(int)Equipment.RightWeapon].subtype == (byte)ItemSubtypeWeapon.Shield) { + dmgReductionByShield += 0.25f; + } + if (attack.Damage > 0) { + attack.Damage *= 1 - dmgReductionByShield; + } + Log.PrintLn(player.entity.name + " " + attack.Target + " " + attack.Damage + " " + attack.Critical, System.ConsoleColor.Magenta); if (attack.Target == player.entity.guid) {//players can't damage themselves. this prevents double self heals since selfheal is already applied locally attack.Damage = 0; } From 8ec16033b8bd0516624bc7a620f3028373ec00d0 Mon Sep 17 00:00:00 2001 From: LastExceed Date: Mon, 15 Oct 2018 11:31:57 +0200 Subject: [PATCH 09/13] move ZoxModel to resources --- {Server/Addon => Resources}/ZoxModel.cs | 2 +- Server/Server.cs | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) rename {Server/Addon => Resources}/ZoxModel.cs (98%) diff --git a/Server/Addon/ZoxModel.cs b/Resources/ZoxModel.cs similarity index 98% rename from Server/Addon/ZoxModel.cs rename to Resources/ZoxModel.cs index b2c3f28..ed311ea 100644 --- a/Server/Addon/ZoxModel.cs +++ b/Resources/ZoxModel.cs @@ -3,7 +3,7 @@ using Resources.Utilities; using Resources.Packet; -namespace Server.Addon { +namespace Resources { class ZoxModel { public string Creator { get; set; } public byte Height { get; set; } diff --git a/Server/Server.cs b/Server/Server.cs index 84b8a94..85d8a8b 100644 --- a/Server/Server.cs +++ b/Server/Server.cs @@ -5,8 +5,6 @@ using System.Net; using System.Net.Sockets; using System.IO; - -using Server.Addon; using Server.Database; using Microsoft.EntityFrameworkCore; @@ -14,7 +12,6 @@ using Resources; using Resources.Datagram; using Resources.Packet; -using Resources.Utilities; namespace Server { public static partial class Server { From 3fc570bd21f5ea75cd1c85c15129c5770c9e0a66 Mon Sep 17 00:00:00 2001 From: LastExceed Date: Mon, 15 Oct 2018 11:43:19 +0200 Subject: [PATCH 10/13] rename Server class to ServerCore to prevent identical named class in a namespace --- Bridge/Bridge.csproj | 2 +- Bridge/{BridgeTCPUDP.cs => BridgeCore.cs} | 2 +- Bridge/FormMain.cs | 10 +++--- Bridge/FormMap.cs | 2 +- Bridge/FormRegister.cs | 32 +++++++++---------- Bridge/KeyboardHook.cs | 6 ++-- Server/Extensions/AntiCheat.cs | 4 +-- Server/Extensions/Balancing.cs | 4 +-- Server/Extensions/ChatCommands.cs | 24 +++++++------- Server/Extensions/Pvp.cs | 2 +- Server/Extensions/SpecialMoves.cs | 10 +++--- Server/Extensions/Tombstones.cs | 8 ++--- Server/Program.cs | 2 +- Server/{Server.cs => ServerCore.cs} | 2 +- ...{Server_Events.cs => ServerCore_Events.cs} | 2 +- 15 files changed, 56 insertions(+), 56 deletions(-) rename Bridge/{BridgeTCPUDP.cs => BridgeCore.cs} (99%) rename Server/{Server.cs => ServerCore.cs} (99%) rename Server/{Server_Events.cs => ServerCore_Events.cs} (97%) diff --git a/Bridge/Bridge.csproj b/Bridge/Bridge.csproj index 1ccf748..f9a563b 100644 --- a/Bridge/Bridge.csproj +++ b/Bridge/Bridge.csproj @@ -112,7 +112,7 @@ - + FormChat.cs diff --git a/Bridge/BridgeTCPUDP.cs b/Bridge/BridgeCore.cs similarity index 99% rename from Bridge/BridgeTCPUDP.cs rename to Bridge/BridgeCore.cs index f6ff3a1..dce5298 100644 --- a/Bridge/BridgeTCPUDP.cs +++ b/Bridge/BridgeCore.cs @@ -15,7 +15,7 @@ using Resources.Datagram; namespace Bridge { - static class BridgeTCPUDP { + static class BridgeCore { public static UdpClient udpToServer; public static TcpClient tcpToServer, tcpToClient; public static TcpListener tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 12345); //hardcoded because client port can't be changed diff --git a/Bridge/FormMain.cs b/Bridge/FormMain.cs index f0d29c4..7c31963 100644 --- a/Bridge/FormMain.cs +++ b/Bridge/FormMain.cs @@ -22,10 +22,10 @@ private void FormMain_Shown(object sender, EventArgs e) { chat.Show(); chat.Top = this.Top; chat.Left = Left + Width; - BridgeTCPUDP.form = this; + BridgeCore.form = this; CwRam.formMain = this; - new Thread(BridgeTCPUDP.ListenFromClientTCP).Start(); - new Thread(BridgeTCPUDP.Connect).Start(); + new Thread(BridgeCore.ListenFromClientTCP).Start(); + new Thread(BridgeCore.Connect).Start(); keyboardHook = new KeyboardHook(); } private void timerSearchProcess_Tick(object sender, EventArgs e) { @@ -39,7 +39,7 @@ private void timerSearchProcess_Tick(object sender, EventArgs e) { } else { CwRam.RemoveFog(); - if (BridgeTCPUDP.status == Resources.BridgeStatus.Playing) CwRam.SetName(linkLabelUser.Text); + if (BridgeCore.status == Resources.BridgeStatus.Playing) CwRam.SetName(linkLabelUser.Text); } } else { @@ -108,7 +108,7 @@ private void buttonLoginRegister_Click(object sender, EventArgs e) { } private void contextMenuStripUser_ItemClicked(object sender, ToolStripItemClickedEventArgs e) { - BridgeTCPUDP.Logout(); + BridgeCore.Logout(); OnLogout(); } public void OnLogout() { diff --git a/Bridge/FormMap.cs b/Bridge/FormMap.cs index 4ebc3ae..2b66665 100644 --- a/Bridge/FormMap.cs +++ b/Bridge/FormMap.cs @@ -13,7 +13,7 @@ public FormMap() { private void Refreshtimer_Tick(object sender, EventArgs e) { Controls.Clear(); playercollection.Clear(); - foreach (var entity in BridgeTCPUDP.dynamicEntities.Values.ToList()) { + foreach (var entity in BridgeCore.dynamicEntities.Values.ToList()) { if (entity.hostility == Resources.Hostility.Player) { Label playerlabel = new Label { Left = (int)entity.position.x / 0x10000, diff --git a/Bridge/FormRegister.cs b/Bridge/FormRegister.cs index aaff13a..6ca0d7f 100644 --- a/Bridge/FormRegister.cs +++ b/Bridge/FormRegister.cs @@ -41,7 +41,7 @@ private void textBoxEmail_TextChanged(object sender, EventArgs e) { private void buttonRegister_Click(object sender, EventArgs e) { buttonRegister.Enabled = false; - BridgeTCPUDP.Register(textBoxUsername.Text, textBoxEmail.Text, textBoxPassword.Text); + BridgeCore.Register(textBoxUsername.Text, textBoxEmail.Text, textBoxPassword.Text); } private void buttonCreate_Click(object sender, EventArgs e) { @@ -77,39 +77,39 @@ private void buttonLogin_Click(object sender, EventArgs e) { textBoxUsername.ReadOnly = true; textBoxEmail.ReadOnly = true; textBoxPassword.ReadOnly = true; - BridgeTCPUDP.Login(textBoxUsername.Text, textBoxPassword.Text); + BridgeCore.Login(textBoxUsername.Text, textBoxPassword.Text); } public void OnLoginResponse(AuthResponse authResponse) { switch (authResponse) { case AuthResponse.Success: - BridgeTCPUDP.form.Log("success\n", Color.Green); - BridgeTCPUDP.form.buttonLoginRegister.Visible = false; - BridgeTCPUDP.form.linkLabelUser.Text = textBoxUsername.Text; - BridgeTCPUDP.form.linkLabelUser.Visible = true; - BridgeTCPUDP.form.buttonClan.Enabled = true; - BridgeTCPUDP.form.buttonClan.Visible = false; - BridgeTCPUDP.form.linkLabelClan.Text = "Prisoners of Irreality"; - BridgeTCPUDP.form.linkLabelClan.Visible = true; + BridgeCore.form.Log("success\n", Color.Green); + BridgeCore.form.buttonLoginRegister.Visible = false; + BridgeCore.form.linkLabelUser.Text = textBoxUsername.Text; + BridgeCore.form.linkLabelUser.Visible = true; + BridgeCore.form.buttonClan.Enabled = true; + BridgeCore.form.buttonClan.Visible = false; + BridgeCore.form.linkLabelClan.Text = "Prisoners of Irreality"; + BridgeCore.form.linkLabelClan.Visible = true; this.Close(); break; case AuthResponse.UnknownUser: - BridgeTCPUDP.form.Log("username does not exist\n", Color.Red); + BridgeCore.form.Log("username does not exist\n", Color.Red); goto default; case AuthResponse.WrongPassword: - BridgeTCPUDP.form.Log("wrong password\n", Color.Red); + BridgeCore.form.Log("wrong password\n", Color.Red); goto default; case AuthResponse.Banned: - BridgeTCPUDP.form.Log("you are banned\n", Color.Red); + BridgeCore.form.Log("you are banned\n", Color.Red); goto default; case AuthResponse.AccountAlreadyActive: - BridgeTCPUDP.form.Log("account already in use\n", Color.Red); + BridgeCore.form.Log("account already in use\n", Color.Red); goto default; case AuthResponse.Unverified: - BridgeTCPUDP.form.Log("unverified (this shouldnt happen)\n", Color.Red); + BridgeCore.form.Log("unverified (this shouldnt happen)\n", Color.Red); goto default; case AuthResponse.UserAlreadyLoggedIn: - BridgeTCPUDP.form.Log("you are already logged in (this shouldn't happen)\n", Color.Red); + BridgeCore.form.Log("you are already logged in (this shouldn't happen)\n", Color.Red); goto default; default: buttonLogin.Enabled = true; diff --git a/Bridge/KeyboardHook.cs b/Bridge/KeyboardHook.cs index 7d3fcdb..5b67069 100644 --- a/Bridge/KeyboardHook.cs +++ b/Bridge/KeyboardHook.cs @@ -100,13 +100,13 @@ private void OnKey(Keys key, bool isDown) { if (!isDown) return;//temp fix to prevent activation on release switch (key) { case Keys.D4: - BridgeTCPUDP.OnHotkey(Resources.HotkeyID.CtrlSpace); + BridgeCore.OnHotkey(Resources.HotkeyID.CtrlSpace); break; case Keys.D5: - BridgeTCPUDP.OnHotkey(Resources.HotkeyID.SpecialMove2); + BridgeCore.OnHotkey(Resources.HotkeyID.SpecialMove2); break; case Keys.D0: - BridgeTCPUDP.OnHotkey(Resources.HotkeyID.TeleportToTown); + BridgeCore.OnHotkey(Resources.HotkeyID.TeleportToTown); break; default: break; diff --git a/Server/Extensions/AntiCheat.cs b/Server/Extensions/AntiCheat.cs index 4684778..a09b08e 100644 --- a/Server/Extensions/AntiCheat.cs +++ b/Server/Extensions/AntiCheat.cs @@ -7,13 +7,13 @@ namespace Server.Extensions { public static class AntiCheat { public static void Init() { - Server.EntityUpdated += That; + ServerCore.EntityUpdated += That; } private static void That(EntityUpdate entityUpdate, Player player) { string ACmessage = Inspect(entityUpdate, player.entity); if (ACmessage != null) { - Server.Kick(player, ACmessage); + ServerCore.Kick(player, ACmessage); } } diff --git a/Server/Extensions/Balancing.cs b/Server/Extensions/Balancing.cs index f70ee1d..11a01be 100644 --- a/Server/Extensions/Balancing.cs +++ b/Server/Extensions/Balancing.cs @@ -4,7 +4,7 @@ namespace Server.Extensions { public static class Balancing { public static void Init() { - Server.EntityAttacked += CutDmgInHalf; + ServerCore.EntityAttacked += CutDmgInHalf; } private static void CutDmgInHalf(Attack attack, Player player) { @@ -14,7 +14,7 @@ private static void CutDmgInHalf(Attack attack, Player player) { //else { // attack.Damage *= 0.333333f; //heal //} - var target = Server.dynamicEntities[attack.Target]; + var target = ServerCore.dynamicEntities[attack.Target]; var dmgReductionByShield = 0f; if (target.equipment[(int)Equipment.LeftWeapon].subtype == (byte)ItemSubtypeWeapon.Shield) { dmgReductionByShield += 0.25f; diff --git a/Server/Extensions/ChatCommands.cs b/Server/Extensions/ChatCommands.cs index 65adc21..56fab56 100644 --- a/Server/Extensions/ChatCommands.cs +++ b/Server/Extensions/ChatCommands.cs @@ -9,7 +9,7 @@ namespace Server.Extensions { public static class ChatCommands { public static void Init() { - Server.ChatMessageReceived += ParseAsCommand; + ServerCore.ChatMessageReceived += ParseAsCommand; } private static void ParseAsCommand(string message, Player source) { @@ -24,16 +24,16 @@ private static void ParseAsCommand(string message, Player source) { case "ban": #region ban if (source.entity.name != "BLACKROCK") { - Server.Notify(source, "no permission"); + ServerCore.Notify(source, "no permission"); break; } if (parameters.Length == 1) { - Server.Notify(source, string.Format("usage example: /kick blackrock")); + ServerCore.Notify(source, string.Format("usage example: /kick blackrock")); break; } - var target = Server.players.FirstOrDefault(x => x.entity.name.Contains(parameters[1])); + var target = ServerCore.players.FirstOrDefault(x => x.entity.name.Contains(parameters[1])); if (target == null) { - Server.Notify(source, "invalid target"); + ServerCore.Notify(source, "invalid target"); break; }; var reason = "no reason specified"; @@ -41,15 +41,15 @@ private static void ParseAsCommand(string message, Player source) { reason = parameters[2]; } if (command == "kick") { - Server.Kick(target, reason); + ServerCore.Kick(target, reason); break; } target.writer.Write((byte)ServerPacketID.BTFO); target.writer.Write(reason); if (command == "ban") { - Server.userDatabase.BanUser(target.entity.name, (int)target.IP.Address, target.MAC, reason); + ServerCore.userDatabase.BanUser(target.entity.name, (int)target.IP.Address, target.MAC, reason); } - Server.RemovePlayerEntity(target, false); + ServerCore.RemovePlayerEntity(target, false); break; #endregion case "bleeding": @@ -58,24 +58,24 @@ private static void ParseAsCommand(string message, Player source) { case "time": #region time if (parameters.Length == 1) { - Server.Notify(source, string.Format("usage example: /time 12:00")); + ServerCore.Notify(source, string.Format("usage example: /time 12:00")); break; } var clock = parameters[1].Split(":"); if (clock.Length < 2 || !int.TryParse(clock[0], out int hour) || !int.TryParse(clock[1], out int minute)) { - Server.Notify(source, string.Format("invalid syntax")); + ServerCore.Notify(source, string.Format("invalid syntax")); break; } var inGameTime = new InGameTime() { Milliseconds = (hour * 60 + minute) * 60000, }; - Server.SendUDP(inGameTime.data, source); + ServerCore.SendUDP(inGameTime.data, source); break; #endregion default: - Server.Notify(source, string.Format("unknown command '{0}'", parameters[0])); + ServerCore.Notify(source, string.Format("unknown command '{0}'", parameters[0])); break; } } diff --git a/Server/Extensions/Pvp.cs b/Server/Extensions/Pvp.cs index 94cb147..fe9a664 100644 --- a/Server/Extensions/Pvp.cs +++ b/Server/Extensions/Pvp.cs @@ -7,7 +7,7 @@ namespace Server.Extensions { public static class Pvp { public static void Init() { - Server.EntityUpdated += EnableFriendlyFireFlag; + ServerCore.EntityUpdated += EnableFriendlyFireFlag; } private static void EnableFriendlyFireFlag(EntityUpdate entityUpdate, Player player) { diff --git a/Server/Extensions/SpecialMoves.cs b/Server/Extensions/SpecialMoves.cs index f12481c..b57e9de 100644 --- a/Server/Extensions/SpecialMoves.cs +++ b/Server/Extensions/SpecialMoves.cs @@ -9,20 +9,20 @@ namespace Server.Extensions { public static class SpecialMoves { public static void Init() { - Server.SpecialMoveUsed += OnSpecialMove; + ServerCore.SpecialMoveUsed += OnSpecialMove; } private static void OnSpecialMove(SpecialMove specialMove, Player source) { switch (specialMove.Id) { case SpecialMoveID.Taunt: - var target = Server.players.FirstOrDefault(p => p.entity.guid == specialMove.Guid); + var target = ServerCore.players.FirstOrDefault(p => p.entity.guid == specialMove.Guid); if (target != null) { specialMove.Guid = (ushort)source.entity.guid; - Server.SendUDP(specialMove.data, target); + ServerCore.SendUDP(specialMove.data, target); } break; case SpecialMoveID.SmokeBomb: - Server.BroadcastUDP(specialMove.data, source); + ServerCore.BroadcastUDP(specialMove.data, source); break; case SpecialMoveID.CursedArrow: case SpecialMoveID.ArrowRain: @@ -30,7 +30,7 @@ private static void OnSpecialMove(SpecialMove specialMove, Player source) { case SpecialMoveID.IceWave: case SpecialMoveID.Confusion: case SpecialMoveID.ShadowStep: - Server.BroadcastUDP(specialMove.data); + ServerCore.BroadcastUDP(specialMove.data); break; default: break; diff --git a/Server/Extensions/Tombstones.cs b/Server/Extensions/Tombstones.cs index 6b6d664..bb7bad5 100644 --- a/Server/Extensions/Tombstones.cs +++ b/Server/Extensions/Tombstones.cs @@ -9,13 +9,13 @@ namespace Server.Extensions { public static class Tombstones { public static void Init() { - Server.EntityUpdated += SpawnTomb; + ServerCore.EntityUpdated += SpawnTomb; } private static void SpawnTomb(EntityUpdate entityUpdate, Player player) { if (entityUpdate.HP <= 0 && (player.entity.HP > 0 || player.entity.HP == null)) { var tombstone = new EntityUpdate() { - guid = Server.AssignGuid(), + guid = ServerCore.AssignGuid(), position = entityUpdate.position ?? player.entity.position, hostility = Hostility.Neutral, entityType = EntityType.None, @@ -32,13 +32,13 @@ private static void SpawnTomb(EntityUpdate entityUpdate, Player player) { name = "tombstone" }; player.tomb = (ushort)tombstone.guid; - Server.BroadcastUDP(tombstone.CreateDatagram()); + ServerCore.BroadcastUDP(tombstone.CreateDatagram()); } else if (player.entity.HP <= 0 && entityUpdate.HP > 0 && player.tomb != null) { var rde = new RemoveDynamicEntity() { Guid = (ushort)player.tomb, }; - Server.BroadcastUDP(rde.data); + ServerCore.BroadcastUDP(rde.data); } } } diff --git a/Server/Program.cs b/Server/Program.cs index e4ee40f..2596c96 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -3,7 +3,7 @@ namespace Server { class Program { static void Main(string[] args) { - Server.Start(12346); + ServerCore.Start(12346); while (true) { Console.ReadLine(); } diff --git a/Server/Server.cs b/Server/ServerCore.cs similarity index 99% rename from Server/Server.cs rename to Server/ServerCore.cs index 85d8a8b..98b9cba 100644 --- a/Server/Server.cs +++ b/Server/ServerCore.cs @@ -14,7 +14,7 @@ using Resources.Packet; namespace Server { - public static partial class Server { + public static partial class ServerCore { public static UdpClient udpClient; public static TcpListener tcpListener; public static List players = new List(); diff --git a/Server/Server_Events.cs b/Server/ServerCore_Events.cs similarity index 97% rename from Server/Server_Events.cs rename to Server/ServerCore_Events.cs index e474318..f79930e 100644 --- a/Server/Server_Events.cs +++ b/Server/ServerCore_Events.cs @@ -15,7 +15,7 @@ namespace Server { public delegate void EntityRemovedEventHandler(RemoveDynamicEntity datagram, Player source); public delegate void SpecialMoveUsedEventHandler(SpecialMove datagram, Player source); - public static partial class Server { + public static partial class ServerCore { public static event EntityUpdatedEventHandler EntityUpdated; public static event EntityAttackedEventHandler EntityAttacked; public static event ProjectileCreatedEventHandler ProjectileCreated; From 4090abab05e2596029bf27f4a26f36e885ae0bab Mon Sep 17 00:00:00 2001 From: LastExceed Date: Tue, 16 Oct 2018 14:17:18 +0200 Subject: [PATCH 11/13] add events in bridge --- Bridge/Bridge.csproj | 5 + Bridge/BridgeCore.cs | 553 ++--------------------- Bridge/BridgeCore_Events.cs | 57 +++ Bridge/Extensions/ExtensionsCore.cs | 15 + Bridge/Extensions/Logging.cs | 57 +++ Bridge/Extensions/NameSubjectToChange.cs | 167 +++++++ Bridge/Extensions/SpecialMoves.cs | 375 +++++++++++++++ Bridge/FormMain.cs | 8 +- Bridge/KeyboardHook.cs | 21 +- Resources/Config.cs | 2 +- Resources/CubeworldNetworking | 2 +- 11 files changed, 731 insertions(+), 531 deletions(-) create mode 100644 Bridge/BridgeCore_Events.cs create mode 100644 Bridge/Extensions/ExtensionsCore.cs create mode 100644 Bridge/Extensions/Logging.cs create mode 100644 Bridge/Extensions/NameSubjectToChange.cs create mode 100644 Bridge/Extensions/SpecialMoves.cs diff --git a/Bridge/Bridge.csproj b/Bridge/Bridge.csproj index f9a563b..63f1953 100644 --- a/Bridge/Bridge.csproj +++ b/Bridge/Bridge.csproj @@ -71,7 +71,12 @@ + + + + + Form diff --git a/Bridge/BridgeCore.cs b/Bridge/BridgeCore.cs index dce5298..61f917b 100644 --- a/Bridge/BridgeCore.cs +++ b/Bridge/BridgeCore.cs @@ -10,12 +10,11 @@ using System.Net.NetworkInformation; using Resources; -using Resources.Utilities; using Resources.Packet; using Resources.Datagram; namespace Bridge { - static class BridgeCore { + public static partial class BridgeCore { public static UdpClient udpToServer; public static TcpClient tcpToServer, tcpToClient; public static TcpListener tcpListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 12345); //hardcoded because client port can't be changed @@ -25,7 +24,6 @@ static class BridgeCore { public static int mapseed; public static FormMain form; public static Dictionary dynamicEntities = new Dictionary(); - public static ushort lastTarget; public static Mutex outgoingMutex = new Mutex(); public static BridgeStatus status = BridgeStatus.Offline; @@ -117,12 +115,11 @@ public static void ListenFromClientTCP() { } while (true) { tcpToClient = tcpListener.AcceptTcpClient(); - form.Log("client connected\n", Color.Green); + ClientConnected?.Invoke(); tcpToClient.ReceiveTimeout = 500; tcpToClient.SendTimeout = 500; - tcpToClient.NoDelay = true; - Stream stream = tcpToClient.GetStream(); + var stream = tcpToClient.GetStream(); creader = new BinaryReader(stream); cwriter = new BinaryWriter(stream); @@ -131,6 +128,7 @@ public static void ListenFromClientTCP() { version = 42069, }); form.Log("client rejected\n", Color.Red); + ClientDisconnected?.Invoke(); continue; } status = BridgeStatus.Playing; @@ -156,8 +154,7 @@ public static void ListenFromClientTCP() { break; } dynamicEntities.Remove(guid); - form.Log("client disconnected\n", Color.Red); - RefreshPlayerlist(); + ClientDisconnected?.Invoke(); } } private static void ListenFromServerTCP() { @@ -191,30 +188,22 @@ private static void ProcessDatagram(byte[] datagram) { case DatagramID.DynamicUpdate: #region entityUpdate var entityUpdate = new EntityUpdate(datagram); + EntityUpdateReceived?.Invoke(entityUpdate); if (status == BridgeStatus.Playing) { - if (entityUpdate.guid == guid) { - CwRam.Teleport(entityUpdate.position); - break; - } SendToClient(entityUpdate); } - if (dynamicEntities.ContainsKey(entityUpdate.guid)) { entityUpdate.Merge(dynamicEntities[entityUpdate.guid]); } else { dynamicEntities.Add(entityUpdate.guid, entityUpdate); } - - if (entityUpdate.name != null) { - RefreshPlayerlist(); - } break; #endregion case DatagramID.Attack: #region attack var attack = new Attack(datagram); - CwRam.Knockback(attack.Direction); + AttackReceived?.Invoke(attack); var hit = new Hit() { target = attack.Target, damage = attack.Damage, @@ -233,7 +222,7 @@ private static void ProcessDatagram(byte[] datagram) { case DatagramID.Projectile: #region Projectile var projectile = new Projectile(datagram); - + ProjectileReceived?.Invoke(projectile); var shoot = new Shoot() { attacker = projectile.Source, position = projectile.Position, @@ -256,22 +245,7 @@ private static void ProcessDatagram(byte[] datagram) { case DatagramID.Proc: #region proc var proc = new Proc(datagram); - if (proc.Type == ProcType.Poison && proc.Target == guid) { - var su = new ServerUpdate(); - su.hits.Add(new Hit() { - damage = proc.Modifier, - target = guid, - position = dynamicEntities[guid].position, - }); - bool tick() { - bool f = status == BridgeStatus.Playing && dynamicEntities[guid].HP > 0; - if (f) { - SendToClient(su); - } - return !f; - } - Tools.DoLater(tick, 500, 7); - } + PassiveProcReceived?.Invoke(proc); var passiveProc = new PassiveProc() { target = proc.Target, type = proc.Type, @@ -285,33 +259,32 @@ bool tick() { case DatagramID.Chat: #region chat var chat = new Chat(datagram); - var chatMessage = new ChatMessage() { - sender = chat.Sender, - message = chat.Text - }; - if (status == BridgeStatus.Playing) SendToClient(chatMessage); - if (chat.Sender == 0) { - form.Log(chat.Text + "\n", Color.Magenta); - } - else { - form.Log(dynamicEntities[chat.Sender].name + ": ", Color.Cyan); - form.Log(chat.Text + "\n", Color.White); + ChatMessageReceived?.Invoke(chat); + if (status == BridgeStatus.Playing) { + var chatMessage = new ChatMessage() { + sender = chat.Sender, + message = chat.Text + }; + SendToClient(chatMessage); } break; #endregion case DatagramID.Time: #region time - var igt = new InGameTime(datagram); - - var time = new Time() { - time = igt.Milliseconds - }; - if (status == BridgeStatus.Playing) SendToClient(time); + var inGameTime = new InGameTime(datagram); + InGameTimeReceived?.Invoke(inGameTime); + if (status == BridgeStatus.Playing) { + var time = new Time() { + time = inGameTime.Milliseconds + }; + SendToClient(time); + } break; #endregion case DatagramID.Interaction: #region interaction var interaction = new Interaction(datagram); + InteractionReceived?.Invoke(interaction); var entityAction = new EntityAction() { chunkX = interaction.ChunkX, chunkY = interaction.ChunkY, @@ -324,7 +297,7 @@ bool tick() { case DatagramID.StaticUpdate: #region staticUpdate var staticUpdate = new StaticUpdate(datagram); - + StaticUpdateReceived?.Invoke(staticUpdate); var staticEntity = new ServerUpdate.StaticEntity() { chunkX = (int)(staticUpdate.Position.x / (65536 * 256)), chunkY = (int)(staticUpdate.Position.y / (65536 * 256)), @@ -348,7 +321,7 @@ bool tick() { case DatagramID.Particle: #region particle var particleDatagram = new Particle(datagram); - + ParticleReceived?.Invoke(particleDatagram); var particleSubPacket = new ServerUpdate.Particle() { position = particleDatagram.Position, velocity = particleDatagram.Velocity, @@ -364,142 +337,28 @@ bool tick() { spread = particleDatagram.Spread }; serverUpdate.particles.Add(particleSubPacket); + writeServerUpdate = true; break; #endregion case DatagramID.RemoveDynamicEntity: #region RemoveDynamicEntity var rde = new RemoveDynamicEntity(datagram); + DynamicEntityRemoved?.Invoke(rde); entityUpdate = new EntityUpdate() { guid = rde.Guid, hostility = (Hostility)255, //workaround for DC because i dont like packet2 HP = 0 }; - if (status == BridgeStatus.Playing) SendToClient(entityUpdate); + if (status == BridgeStatus.Playing) { + SendToClient(entityUpdate); + } dynamicEntities.Remove(rde.Guid); - RefreshPlayerlist(); break; #endregion case DatagramID.SpecialMove: #region speicalMove var specialMove = new SpecialMove(datagram); - switch (specialMove.Id) { - case SpecialMoveID.Taunt: - if (dynamicEntities.ContainsKey(specialMove.Guid)) { - if (status == BridgeStatus.Playing) { - CwRam.Teleport(dynamicEntities[specialMove.Guid].position); - CwRam.Freeze(5000); - } - } - break; - case SpecialMoveID.CursedArrow: - break; - case SpecialMoveID.ArrowRain: - break; - case SpecialMoveID.Shrapnel: - var su = new ServerUpdate(); - var blood_hit = new Hit() { - damage = 5f, - target = specialMove.Guid, - }; - su.hits.Add(blood_hit); - var blood_particles = new ServerUpdate.Particle() { - count = 10, - spread = 2f, - type = ParticleType.Normal, - size = 0.1f, - velocity = new FloatVector() { - z = 1f, - }, - color = new FloatVector() { - x = 1f, - y = 0f, - z = 0f - }, - alpha = 1f, - }; - su.particles.Add(blood_particles); - bool tick() { - bool f = status == BridgeStatus.Playing && dynamicEntities[specialMove.Guid].HP > 0; - if (f) { - blood_hit.position = blood_particles.position = dynamicEntities[specialMove.Guid].position; - SendToClient(su); - } - return !f; - } - Tools.DoLater(tick, 50, 100); - break; - case SpecialMoveID.SmokeBomb: - serverUpdate.particles.Add(new ServerUpdate.Particle() { - count = 1000, - spread = 5f, - type = ParticleType.NoGravity, - size = 5f, - velocity = new Resources.Utilities.FloatVector(), - color = new Resources.Utilities.FloatVector() { - x = 1f, - y = 1f, - z = 1f - }, - alpha = 1f, - position = dynamicEntities[specialMove.Guid].position - }); - writeServerUpdate = true; - break; - case SpecialMoveID.IceWave: - if (specialMove.Guid != guid) {//distance small enough - CwRam.Freeze(3000); - } - serverUpdate.particles.Add(new ServerUpdate.Particle() { - count = 100, - spread = 4f, - type = ParticleType.NoGravity, - size = 0.3f, - velocity = new FloatVector(), - color = new FloatVector() { - x = 0f, - y = 1f, - z = 1f - }, - alpha = 1f, - position = dynamicEntities[specialMove.Guid].position - }); - serverUpdate.particles.Add(new ServerUpdate.Particle() { - count = 100, - spread = 10f, - type = ParticleType.NoGravity, - size = 0.1f, - velocity = new FloatVector(), - color = new FloatVector() { - x = 1f, - y = 1f, - z = 1f - }, - alpha = 1f, - position = dynamicEntities[specialMove.Guid].position - }); - serverUpdate.particles.Add(new ServerUpdate.Particle() { - count = 100, - spread = 2f, - type = ParticleType.NoGravity, - size = 0.7f, - velocity = new FloatVector(), - color = new FloatVector() { - x = 0f, - y = 0f, - z = 1f - }, - alpha = 1f, - position = dynamicEntities[specialMove.Guid].position - }); - writeServerUpdate = true; - break; - case SpecialMoveID.Confusion: - break; - case SpecialMoveID.ShadowStep: - break; - default: - break; - } + SpecialMoveReceived?.Invoke(specialMove); break; #endregion default: @@ -513,6 +372,7 @@ private static void ProcessClientPacket(int packetID) { case PacketID.EntityUpdate: #region entityUpdate var entityUpdate = new EntityUpdate(creader); + EntityUpdateSent?.Invoke(entityUpdate); if (dynamicEntities.ContainsKey(entityUpdate.guid)) { entityUpdate.Filter(dynamicEntities[entityUpdate.guid]); entityUpdate.Merge(dynamicEntities[entityUpdate.guid]); @@ -520,9 +380,6 @@ private static void ProcessClientPacket(int packetID) { else { dynamicEntities.Add(entityUpdate.guid, entityUpdate); } - if (entityUpdate.name != null) { - RefreshPlayerlist(); - } if (!entityUpdate.IsEmpty) { SendUDP(entityUpdate.CreateDatagram()); } @@ -530,60 +387,14 @@ private static void ProcessClientPacket(int packetID) { #endregion case PacketID.EntityAction: #region entity action - EntityAction entityAction = new EntityAction(creader); - switch (entityAction.type) { - case ActionType.Talk: - #region Talk - break; - #endregion - case ActionType.StaticInteraction: - #region StaticInteraction - ChatMessage x = new ChatMessage() { - message = "You can't use this, your hands are too small.", - sender = 0 - }; - SendToClient(x); - break; - #endregion - case ActionType.PickUp: - #region PickUp - break; - #endregion - case ActionType.Drop: //send item back to dropper because dropping is disabled to prevent chatspam - #region Drop - if (form.radioButtonDestroy.Checked) { - SendToClient(new ChatMessage() { - message = "item destroyed", - sender = 0, - }); - } - else { - var serverUpdate = new ServerUpdate(); - var pickup = new ServerUpdate.Pickup() { - guid = guid, - item = entityAction.item - }; - serverUpdate.pickups.Add(pickup); - if (form.radioButtonDuplicate.Checked) { - serverUpdate.pickups.Add(pickup); - } - SendToClient(serverUpdate); - } - break; - #endregion - case ActionType.CallPet: - #region CallPet - break; - #endregion - default: - //unknown type - break; - } + var entityAction = new EntityAction(creader); + EntityActionSent?.Invoke(entityAction); break; #endregion case PacketID.Hit: #region hit var hit = new Hit(creader); + HitSent?.Invoke(hit); var attack = new Attack() { Target = (ushort)hit.target, Damage = hit.damage, @@ -595,57 +406,12 @@ private static void ProcessClientPacket(int packetID) { Critical = hit.critical }; SendUDP(attack.data); - lastTarget = attack.Target; break; #endregion case PacketID.PassiveProc: #region passiveProc var passiveProc = new PassiveProc(creader); - switch (passiveProc.type) { - case ProcType.Bulwalk: - SendToClient(new ChatMessage() { - message = string.Format("bulwalk: {0}% dmg reduction", 1.0f - passiveProc.modifier), - sender = 0, - }); - break; - case ProcType.WarFrenzy: - CwRam.PlayerEntity.BossBuff = true; - bool DisableBossBuff() { - bool f = status == BridgeStatus.Playing && dynamicEntities[guid].HP > 0; - if (f) { - CwRam.PlayerEntity.BossBuff = false; - } - return !f; - } - Tools.DoLater(DisableBossBuff, passiveProc.duration, 1); - break; - case ProcType.Camouflage: - break; - case ProcType.Poison: - break; - case ProcType.UnknownA: - break; - case ProcType.ManaShield: - SendToClient(new ChatMessage() { - message = string.Format("manashield: {0}", passiveProc.modifier), - sender = 0, - }); - break; - case ProcType.UnknownB: - break; - case ProcType.UnknownC: - break; - case ProcType.FireSpark: - break; - case ProcType.Intuition: - break; - case ProcType.Elusiveness: - break; - case ProcType.Swiftness: - break; - default: - break; - } + PassiveProcSent?.Invoke(passiveProc); var proc = new Proc() { Target = (ushort)passiveProc.target, Type = passiveProc.type, @@ -658,6 +424,7 @@ bool DisableBossBuff() { case PacketID.Shoot: #region shoot var shoot = new Shoot(creader); + ShotSent?.Invoke(shoot); var projectile = new Projectile() { Position = shoot.position, Velocity = shoot.velocity, @@ -672,26 +439,7 @@ bool DisableBossBuff() { case PacketID.Chat: #region chat var chatMessage = new ChatMessage(creader); - if (chatMessage.message.ToLower() == @"/plane") { - Console.Beep(); - var serverUpdate = new ServerUpdate() { - blockDeltas = new Vox("model.vox").Parse(), - }; - foreach (var block in serverUpdate.blockDeltas) { - block.position.x += 0x802080;//(int)(dynamicEntities[guid].position.x / 0x10000);//8286946; - block.position.y += 0x802080;//(int)(dynamicEntities[guid].position.y / 0x10000);//8344456; - block.position.z += 150;// (int)(dynamicEntities[guid].position.z / 0x10000);//220; - } - SendToClient(serverUpdate); - } - if (chatMessage.message.ToLower() == @"/spawn") { - CwRam.Teleport(new LongVector() { - x = 0x8020800000, - y = 0x8020800000, - z = 0, - }); - break; - } + ChatMessageSent?.Invoke(chatMessage); var chat = new Chat() { Sender = guid,//client doesn't send this Text = chatMessage.message @@ -702,16 +450,19 @@ bool DisableBossBuff() { case PacketID.Chunk: #region chunk var chunk = new Chunk(creader); + ChunkDiscovered?.Invoke(chunk); break; #endregion case PacketID.Sector: #region sector var sector = new Sector(creader); + SectorDiscovered?.Invoke(sector); break; #endregion case PacketID.Version: #region version var version = new ProtocolVersion(creader); + VersionSent?.Invoke(version); if (version.version != 3) { version.version = 3; SendToClient(version); @@ -802,224 +553,10 @@ private static void ProcessServerPacket(int packetID) { } } - public static void RefreshPlayerlist() { - form.Invoke((Action)form.listBoxPlayers.Items.Clear); - foreach (var dynamicEntity in dynamicEntities.Values.ToList()) { - if (dynamicEntity.hostility == Hostility.Player) { - form.Invoke(new Action(() => form.listBoxPlayers.Items.Add(dynamicEntity.name))); - } - } - } - - public static void OnHotkey(HotkeyID hotkey) { - if (CwRam.AnyInterfaceOpen) return; - if (hotkey == HotkeyID.TeleportToTown) { - CwRam.SetMode(Mode.Teleport_To_City, 0); - return; - } - var notification = new ChatMessage() { - sender = 0, - }; - bool spec = dynamicEntities[guid].specialization == 1; - switch (dynamicEntities[guid].entityClass) { - case EntityClass.Rogue when spec: - #region ninja - if (hotkey == HotkeyID.CtrlSpace) { - #region dash - notification.message = "using [dash]"; - CwRam.SetMode(Mode.Spin_Run, 0); - #endregion - } - else { - #region blink - notification.message = "using [blink]"; - if (dynamicEntities.ContainsKey(lastTarget)) { - CwRam.Teleport(dynamicEntities[lastTarget].position); - } - #endregion - } - break; - #endregion - case EntityClass.Rogue: - #region assassin - if (hotkey == HotkeyID.CtrlSpace) { - #region confusion - notification.message = "TODO: [confusion]"; - var specialMove = new SpecialMove() { - Guid = guid, - Id = SpecialMoveID.Confusion, - }; - SendUDP(specialMove.data); - #endregion - } - else { - #region shadow step - notification.message = "TOD: [shadow step]"; - var specialMove = new SpecialMove() { - Guid = guid, - Id = SpecialMoveID.ShadowStep, - }; - SendUDP(specialMove.data); - #endregion - } - break; - #endregion - case EntityClass.Warrior when spec: - #region guardian - if (hotkey == HotkeyID.CtrlSpace) { - #region taunt - notification.message = "using [taunt]"; - var specialMove = new SpecialMove() { - Guid = lastTarget, - Id = SpecialMoveID.Taunt, - }; - SendUDP(specialMove.data); - #endregion - } - else { - #region steel wall - notification.message = "using [steel wall]"; - CwRam.SetMode(Mode.Boss_Skill_Block, 0); - #endregion - } - break; - #endregion - case EntityClass.Warrior: - #region berserk - if (hotkey == HotkeyID.CtrlSpace) { - #region boulder toss - notification.message = "using [boulder toss]"; - CwRam.SetMode(Mode.Boulder_Toss, 0); - #endregion - } - else { - #region earth shatter - notification.message = "using [earth shatter]"; - CwRam.SetMode(Mode.Earth_Shatter, 0); - #endregion - } - break; - #endregion - case EntityClass.Mage when spec: - #region watermage - if (hotkey == HotkeyID.CtrlSpace) { - #region splash - notification.message = "using [splash]"; - CwRam.SetMode(Mode.Splash, 0); - #endregion - } - else { - #region ice wave - notification.message = "using [ice wave]"; - var specialMove = new SpecialMove() { - Guid = guid, - Id = SpecialMoveID.IceWave, - }; - SendUDP(specialMove.data); - #endregion - } - break; - #endregion - case EntityClass.Mage: - #region firemage - if (hotkey == HotkeyID.CtrlSpace) { - #region lava - notification.message = "using [lava]"; - CwRam.SetMode(Mode.Lava, 0); - #endregion - } - else { - #region beam - notification.message = "using [fire ray]"; - CwRam.SetMode(Mode.FireRay, 0); - #endregion - } - break; - #endregion - case EntityClass.Ranger when spec: - #region scout - if (hotkey == HotkeyID.CtrlSpace) { - #region shrapnel - notification.message = "using [shrapnel] bleeding test"; - var specialMove = new SpecialMove() { - Guid = guid, - Id = SpecialMoveID.Shrapnel, - }; - SendUDP(specialMove.data); - #endregion - } - else { - #region smoke bomb - notification.message = "using [smoke bomb]"; - var specialMove = new SpecialMove() { - Guid = guid, - Id = SpecialMoveID.SmokeBomb, - }; - SendUDP(specialMove.data); - - var fakeSmoke = new ServerUpdate(); - fakeSmoke.particles.Add(new ServerUpdate.Particle() { - count = 1000, - spread = 5f, - type = ParticleType.NoGravity, - size = 0.3f, - velocity = new Resources.Utilities.FloatVector(), - color = new Resources.Utilities.FloatVector() { - x = 1f, - y = 1f, - z = 1f - }, - alpha = 1f, - position = dynamicEntities[specialMove.Guid].position - }); - SendToClient(fakeSmoke); - #endregion - } - break; - #endregion - case EntityClass.Ranger: - #region sniper - if (hotkey == HotkeyID.CtrlSpace) { - #region cursed arrow - //TODO - notification.message = "TODO: [cursed arrow]"; - #endregion - } - else { - #region arrow rain - //TODO - notification.message = "TODO: [arrow rain]"; - //const int rainSize = 7; - //for (int x = 0; x < rainSize; x++) { - // for (int y = 0; y < rainSize; y++) { - // var projectile = new Projectile() { - // Scale = 1f, - // Type = ProjectileType.Arrow, - // Source = guid, - // Velocity = new FloatVector() { x = 0, y = 0, z = -1f }, - // Position = new LongVector() { - // x = 0x8020800000,//dynamicEntities[guid].position.x + (long)((dynamicEntities[guid].rayHit.x + x - rainSize / 2) * 0x10000), - // y = 0x8020800000,//dynamicEntities[guid].position.y + (long)((dynamicEntities[guid].rayHit.y + y - rainSize / 2) * 0x10000), - // z = 0x01000000,//dynamicEntities[guid].position.z + (long)((dynamicEntities[guid].rayHit.z + 10) * 0x10000), - // } - // }; - // SendUDP(projectile.data); - // ProcessDatagram(projectile.data); - // } - //} - #endregion - } - break; - #endregion - } - CwRam.memory.WriteInt(CwRam.EntityStart + 0x1164, 3);//mana cubes - SendToClient(notification); - } - - private static void SendUDP(byte[] data) { + public static void SendUDP(byte[] data) { udpToServer.Send(data, data.Length); } - private static void SendToClient(Packet packet) { + public static void SendToClient(Packet packet) { outgoingMutex.WaitOne(); try { packet.Write(cwriter); diff --git a/Bridge/BridgeCore_Events.cs b/Bridge/BridgeCore_Events.cs new file mode 100644 index 0000000..b4c452a --- /dev/null +++ b/Bridge/BridgeCore_Events.cs @@ -0,0 +1,57 @@ +using Resources.Datagram; +using Resources.Packet; +using System; + +namespace Bridge { + public delegate void EntityUpdateSentEventHandler(EntityUpdate entityUpdate); + public delegate void EntityActionSentEventHandler(EntityAction entityAction); + public delegate void HitSentHandler(Hit hit); + public delegate void PassiveProcSentEventHandler(PassiveProc passiveProc); + public delegate void ShotSentHandler(Shoot shoot); + public delegate void ChatMessageSentEventHandler(ChatMessage chatMessage); + public delegate void ChunkDiscoveredEventHandler(Chunk chunk); + public delegate void SectorDiscoveredEventHandler(Sector sector); + public delegate void VersionSentEventHandler(ProtocolVersion protocolVersion); + + public delegate void EntityUpdateReceivedEventHandler(EntityUpdate entityUpdate); + public delegate void AttackReceivedEventHandler(Attack attack); + public delegate void ProjectileReceivedEventHandler(Projectile projectile); + public delegate void PassiveProcReceivedEventHandler(Proc proc); + public delegate void ChatMessageReceivedEventHandler(Chat chat); + public delegate void InGameTimeReceivedEventHandler(InGameTime inGameTime); + public delegate void InteractionReceivedEventHandler(Interaction interaction); + public delegate void StaticUpdateReceivedEventHandler(StaticUpdate staticUpdate); + public delegate void ParticleReceivedEventHandler(Particle particle); + public delegate void DynamicEntityRemovedEventHandler(RemoveDynamicEntity removeDynamicEntity); + public delegate void SpecialMoveReceiveddEventHandler(SpecialMove specialMove); + + public delegate void ClientConnectedEventHandler(); + public delegate void ClientDisconnectedEventHandler(); + + public static partial class BridgeCore { + public static event EntityUpdateSentEventHandler EntityUpdateSent; + public static event EntityActionSentEventHandler EntityActionSent; + public static event HitSentHandler HitSent; + public static event PassiveProcSentEventHandler PassiveProcSent; + public static event ShotSentHandler ShotSent; + public static event ChatMessageSentEventHandler ChatMessageSent; + public static event ChunkDiscoveredEventHandler ChunkDiscovered; + public static event SectorDiscoveredEventHandler SectorDiscovered; + public static event VersionSentEventHandler VersionSent; + + public static event EntityUpdateReceivedEventHandler EntityUpdateReceived; + public static event AttackReceivedEventHandler AttackReceived; + public static event ProjectileReceivedEventHandler ProjectileReceived; + public static event PassiveProcReceivedEventHandler PassiveProcReceived; + public static event ChatMessageReceivedEventHandler ChatMessageReceived; + public static event InGameTimeReceivedEventHandler InGameTimeReceived; + public static event InteractionReceivedEventHandler InteractionReceived; + public static event StaticUpdateReceivedEventHandler StaticUpdateReceived; + public static event ParticleReceivedEventHandler ParticleReceived; + public static event DynamicEntityRemovedEventHandler DynamicEntityRemoved; + public static event SpecialMoveReceiveddEventHandler SpecialMoveReceived; + + public static event ClientConnectedEventHandler ClientConnected; + public static event ClientDisconnectedEventHandler ClientDisconnected; + } +} diff --git a/Bridge/Extensions/ExtensionsCore.cs b/Bridge/Extensions/ExtensionsCore.cs new file mode 100644 index 0000000..db7fda9 --- /dev/null +++ b/Bridge/Extensions/ExtensionsCore.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bridge.Extensions { + public static class ExtensionsCore { + public static void Init() { + Logging.Init(); + NameSubjectToChange.Init(); + SpecialMoves.Init(); + } + } +} diff --git a/Bridge/Extensions/Logging.cs b/Bridge/Extensions/Logging.cs new file mode 100644 index 0000000..ed91b3e --- /dev/null +++ b/Bridge/Extensions/Logging.cs @@ -0,0 +1,57 @@ +using Resources; +using Resources.Datagram; +using Resources.Packet; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Bridge.Extensions { + public static class Logging { + public static void Init() { + BridgeCore.ChatMessageReceived += ChatLog; + BridgeCore.ClientConnected += LogConnect; + BridgeCore.ClientDisconnected += LogDisconnect; + + BridgeCore.EntityUpdateReceived += CheckForNewName; + BridgeCore.EntityUpdateSent += CheckForNewName; + BridgeCore.DynamicEntityRemoved += RemoveNameFromList; + BridgeCore.ClientDisconnected += RefreshPlayerlist; + } + + private static void ChatLog(Chat chat) { + if (chat.Sender == 0) { + BridgeCore.form.Log(chat.Text + "\n", Color.Magenta); + } + else { + BridgeCore.form.Log(BridgeCore.dynamicEntities[chat.Sender].name + ": ", Color.Cyan); + BridgeCore.form.Log(chat.Text + "\n", Color.White); + } + } + private static void LogConnect() { + BridgeCore.form.Log("client connected\n", Color.Green); + } + private static void LogDisconnect() { + BridgeCore.form.Log("client disconnected\n", Color.Red); + } + + private static void CheckForNewName(EntityUpdate entityUpdate) { + if (entityUpdate.name != null) { + RefreshPlayerlist(); + } + } + private static void RemoveNameFromList(RemoveDynamicEntity rde) { + RefreshPlayerlist(); + } + private static void RefreshPlayerlist() { + BridgeCore.form.Invoke((Action)BridgeCore.form.listBoxPlayers.Items.Clear); + foreach (var dynamicEntity in BridgeCore.dynamicEntities.Values.ToList()) { + if (dynamicEntity.hostility == Hostility.Player) { + BridgeCore.form.Invoke(new Action(() => BridgeCore.form.listBoxPlayers.Items.Add(dynamicEntity.name))); + } + } + } + } +} diff --git a/Bridge/Extensions/NameSubjectToChange.cs b/Bridge/Extensions/NameSubjectToChange.cs new file mode 100644 index 0000000..daef5f1 --- /dev/null +++ b/Bridge/Extensions/NameSubjectToChange.cs @@ -0,0 +1,167 @@ +using Resources; +using Resources.Datagram; +using Resources.Packet; +using Resources.Utilities; +using System; +using System.Drawing; +using System.Linq; + +namespace Bridge.Extensions { + public static class NameSubjectToChange { + public static void Init() { + BridgeCore.EntityUpdateReceived += Teleport; + BridgeCore.AttackReceived += Knockback; + BridgeCore.PassiveProcReceived += Poison; + BridgeCore.EntityActionSent += HandleEntityAction; + } + + private static void Teleport(EntityUpdate entityUpdate) { + if (BridgeCore.status == BridgeStatus.Playing) { + if (entityUpdate.guid == BridgeCore.guid) { + CwRam.Teleport(entityUpdate.position); + //todo: prevent packet from being sent to client + } + } + } + private static void Knockback(Attack attack) { + CwRam.Knockback(attack.Direction); + } + private static void Poison(Proc proc) { + if (proc.Type == ProcType.Poison && proc.Target == BridgeCore.guid) { + var su = new ServerUpdate(); + su.hits.Add(new Hit() { + damage = proc.Modifier, + target = BridgeCore.guid, + position = BridgeCore.dynamicEntities[BridgeCore.guid].position, + }); + bool tick() { + bool f = BridgeCore.status == BridgeStatus.Playing && BridgeCore.dynamicEntities[BridgeCore.guid].HP > 0; + if (f) { + BridgeCore.SendToClient(su); + } + return !f; + } + Tools.DoLater(tick, 500, 7); + } + } + + private static void HandleEntityAction(EntityAction entityAction) { + switch (entityAction.type) { + case ActionType.Talk: + #region Talk + break; + #endregion + case ActionType.StaticInteraction: + #region StaticInteraction + ChatMessage x = new ChatMessage() { + message = "static interation is disabled", + sender = 0 + }; + BridgeCore.SendToClient(x); + break; + #endregion + case ActionType.PickUp: + #region PickUp + break; + #endregion + case ActionType.Drop: //send item back to dropper because dropping is disabled to prevent chatspam + #region Drop + if (BridgeCore.form.radioButtonDestroy.Checked) { + BridgeCore.SendToClient(new ChatMessage() { + message = "item destroyed", + sender = 0, + }); + } + else { + var serverUpdate = new ServerUpdate(); + var pickup = new ServerUpdate.Pickup() { + guid = BridgeCore.guid, + item = entityAction.item + }; + serverUpdate.pickups.Add(pickup); + if (BridgeCore.form.radioButtonDuplicate.Checked) { + serverUpdate.pickups.Add(pickup); + } + BridgeCore.SendToClient(serverUpdate); + } + break; + #endregion + case ActionType.CallPet: + #region CallPet + break; + #endregion + default: + //unknown type + break; + } + } + private static void HandlePassiveProc(PassiveProc passiveProc) { + switch (passiveProc.type) { + case ProcType.Bulwalk: + BridgeCore.SendToClient(new ChatMessage() { + message = string.Format("bulwalk: {0}% dmg reduction", 1.0f - passiveProc.modifier), + sender = 0, + }); + break; + case ProcType.WarFrenzy: + CwRam.PlayerEntity.BossBuff = true; + bool DisableBossBuff() { + bool f = BridgeCore.status == BridgeStatus.Playing && BridgeCore.dynamicEntities[BridgeCore.guid].HP > 0; + if (f) { + CwRam.PlayerEntity.BossBuff = false; + } + return !f; + } + Tools.DoLater(DisableBossBuff, passiveProc.duration, 1); + break; + case ProcType.Camouflage: + break; + case ProcType.Poison: + break; + case ProcType.UnknownA: + break; + case ProcType.ManaShield: + BridgeCore.SendToClient(new ChatMessage() { + message = string.Format("manashield: {0}", passiveProc.modifier), + sender = 0, + }); + break; + case ProcType.UnknownB: + break; + case ProcType.UnknownC: + break; + case ProcType.FireSpark: + break; + case ProcType.Intuition: + break; + case ProcType.Elusiveness: + break; + case ProcType.Swiftness: + break; + default: + break; + } + } + private static void ClientSideChatCommands(ChatMessage chatMessage) { + if (chatMessage.message.ToLower() == @"/plane") { + Console.Beep(); + var serverUpdate = new ServerUpdate() { + blockDeltas = new Vox("model.vox").Parse(), + }; + foreach (var block in serverUpdate.blockDeltas) { + block.position.x += 0x802080;//(int)(dynamicEntities[guid].position.x / 0x10000);//8286946; + block.position.y += 0x802080;//(int)(dynamicEntities[guid].position.y / 0x10000);//8344456; + block.position.z += 150;// (int)(dynamicEntities[guid].position.z / 0x10000);//220; + } + BridgeCore.SendToClient(serverUpdate); + } + if (chatMessage.message.ToLower() == @"/spawn") { + CwRam.Teleport(new LongVector() { + x = 0x8020800000, + y = 0x8020800000, + z = 0, + }); + } + } + } +} diff --git a/Bridge/Extensions/SpecialMoves.cs b/Bridge/Extensions/SpecialMoves.cs new file mode 100644 index 0000000..0da06c8 --- /dev/null +++ b/Bridge/Extensions/SpecialMoves.cs @@ -0,0 +1,375 @@ +using Resources; +using Resources.Datagram; +using Resources.Packet; +using Resources.Utilities; +using System.Windows.Forms; + +namespace Bridge.Extensions { + public static class SpecialMoves { + private static ushort lastTarget; + + public static void Init() { + BridgeCore.HitSent += RememberLastTarget; + BridgeCore.SpecialMoveReceived += HandleSpecialMoves; + BridgeCore.ClientConnected += EnableHotkeys; + BridgeCore.ClientDisconnected += DisableHotkeys; + } + + private static void RememberLastTarget(Hit hit) { + lastTarget = (ushort)hit.target; + } + private static void HandleSpecialMoves(SpecialMove specialMove) { + switch (specialMove.Id) { + case SpecialMoveID.Taunt: + if (BridgeCore.dynamicEntities.ContainsKey(specialMove.Guid)) { + if (BridgeCore.status == BridgeStatus.Playing) { + CwRam.Teleport(BridgeCore.dynamicEntities[specialMove.Guid].position); + CwRam.Freeze(5000); + } + } + break; + case SpecialMoveID.CursedArrow: + break; + case SpecialMoveID.ArrowRain: + break; + case SpecialMoveID.Shrapnel: + var su = new ServerUpdate(); + var blood_hit = new Hit() { + damage = 5f, + target = specialMove.Guid, + }; + su.hits.Add(blood_hit); + var blood_particles = new ServerUpdate.Particle() { + count = 10, + spread = 2f, + type = ParticleType.Normal, + size = 0.1f, + velocity = new FloatVector() { + z = 1f, + }, + color = new FloatVector() { + x = 1f, + y = 0f, + z = 0f + }, + alpha = 1f, + }; + su.particles.Add(blood_particles); + bool tick() { + bool f = BridgeCore.status == BridgeStatus.Playing && BridgeCore.dynamicEntities[specialMove.Guid].HP > 0; + if (f) { + blood_hit.position = blood_particles.position = BridgeCore.dynamicEntities[specialMove.Guid].position; + BridgeCore.SendToClient(su); + } + return !f; + } + Tools.DoLater(tick, 50, 100); + break; + case SpecialMoveID.SmokeBomb: + var serverUpdate = new ServerUpdate(); + serverUpdate.particles.Add(new ServerUpdate.Particle() { + count = 1000, + spread = 5f, + type = ParticleType.NoGravity, + size = 5f, + velocity = new FloatVector(), + color = new FloatVector() { + x = 1f, + y = 1f, + z = 1f + }, + alpha = 1f, + position = BridgeCore.dynamicEntities[specialMove.Guid].position + }); + if (BridgeCore.status == BridgeStatus.Playing) { + BridgeCore.SendToClient(serverUpdate); + } + break; + case SpecialMoveID.IceWave: + if (specialMove.Guid != BridgeCore.guid) {//distance small enough + CwRam.Freeze(3000); + } + serverUpdate = new ServerUpdate(); + serverUpdate.particles.Add(new ServerUpdate.Particle() { + count = 100, + spread = 4f, + type = ParticleType.NoGravity, + size = 0.3f, + velocity = new FloatVector(), + color = new FloatVector() { + x = 0f, + y = 1f, + z = 1f + }, + alpha = 1f, + position = BridgeCore.dynamicEntities[specialMove.Guid].position + }); + serverUpdate.particles.Add(new ServerUpdate.Particle() { + count = 100, + spread = 10f, + type = ParticleType.NoGravity, + size = 0.1f, + velocity = new FloatVector(), + color = new FloatVector() { + x = 1f, + y = 1f, + z = 1f + }, + alpha = 1f, + position = BridgeCore.dynamicEntities[specialMove.Guid].position + }); + serverUpdate.particles.Add(new ServerUpdate.Particle() { + count = 100, + spread = 2f, + type = ParticleType.NoGravity, + size = 0.7f, + velocity = new FloatVector(), + color = new FloatVector() { + x = 0f, + y = 0f, + z = 1f + }, + alpha = 1f, + position = BridgeCore.dynamicEntities[specialMove.Guid].position + }); + if (BridgeCore.status == BridgeStatus.Playing) { + BridgeCore.SendToClient(serverUpdate); + } + break; + case SpecialMoveID.Confusion: + break; + case SpecialMoveID.ShadowStep: + break; + default: + break; + } + } + + private static void EnableHotkeys() { + BridgeCore.form.keyboardHook.KeyboardChanged += OnKeyboardChanged; + } + private static void DisableHotkeys() { + BridgeCore.form.keyboardHook.KeyboardChanged -= OnKeyboardChanged; + } + private static void OnKeyboardChanged(Keys key, bool isDown) { + switch (key) { + case Keys.D4 when isDown: + OnHotkey(HotkeyID.CtrlSpace); + break; + case Keys.D5 when isDown: + OnHotkey(HotkeyID.SpecialMove2); + break; + case Keys.D0 when isDown: + OnHotkey(HotkeyID.TeleportToTown); + break; + default: + break; + } + } + private static void OnHotkey(HotkeyID hotkey) { + if (CwRam.AnyInterfaceOpen) return; + + if (hotkey == HotkeyID.TeleportToTown) { + CwRam.SetMode(Mode.Teleport_To_City, 0); + return; + } + var notification = new ChatMessage() { + sender = 0, + }; + bool spec = BridgeCore.dynamicEntities[BridgeCore.guid].specialization == 1; + switch (BridgeCore.dynamicEntities[BridgeCore.guid].entityClass) { + case EntityClass.Rogue when spec: + #region ninja + if (hotkey == HotkeyID.CtrlSpace) { + #region dash + notification.message = "using [dash]"; + CwRam.SetMode(Mode.Spin_Run, 0); + #endregion + } + else { + #region blink + notification.message = "using [blink]"; + if (BridgeCore.dynamicEntities.ContainsKey(lastTarget)) { + CwRam.Teleport(BridgeCore.dynamicEntities[lastTarget].position); + } + #endregion + } + break; + #endregion + case EntityClass.Rogue: + #region assassin + if (hotkey == HotkeyID.CtrlSpace) { + #region confusion + notification.message = "TODO: [confusion]"; + var specialMove = new SpecialMove() { + Guid = BridgeCore.guid, + Id = SpecialMoveID.Confusion, + }; + BridgeCore.SendUDP(specialMove.data); + #endregion + } + else { + #region shadow step + notification.message = "TOD: [shadow step]"; + var specialMove = new SpecialMove() { + Guid = BridgeCore.guid, + Id = SpecialMoveID.ShadowStep, + }; + BridgeCore.SendUDP(specialMove.data); + #endregion + } + break; + #endregion + case EntityClass.Warrior when spec: + #region guardian + if (hotkey == HotkeyID.CtrlSpace) { + #region taunt + notification.message = "using [taunt]"; + var specialMove = new SpecialMove() { + Guid = lastTarget, + Id = SpecialMoveID.Taunt, + }; + BridgeCore.SendUDP(specialMove.data); + #endregion + } + else { + #region steel wall + notification.message = "using [steel wall]"; + CwRam.SetMode(Mode.Boss_Skill_Block, 0); + #endregion + } + break; + #endregion + case EntityClass.Warrior: + #region berserk + if (hotkey == HotkeyID.CtrlSpace) { + #region boulder toss + notification.message = "using [boulder toss]"; + CwRam.SetMode(Mode.Boulder_Toss, 0); + #endregion + } + else { + #region earth shatter + notification.message = "using [earth shatter]"; + CwRam.SetMode(Mode.Earth_Shatter, 0); + #endregion + } + break; + #endregion + case EntityClass.Mage when spec: + #region watermage + if (hotkey == HotkeyID.CtrlSpace) { + #region splash + notification.message = "using [splash]"; + CwRam.SetMode(Mode.Splash, 0); + #endregion + } + else { + #region ice wave + notification.message = "using [ice wave]"; + var specialMove = new SpecialMove() { + Guid = BridgeCore.guid, + Id = SpecialMoveID.IceWave, + }; + BridgeCore.SendUDP(specialMove.data); + #endregion + } + break; + #endregion + case EntityClass.Mage: + #region firemage + if (hotkey == HotkeyID.CtrlSpace) { + #region lava + notification.message = "using [lava]"; + CwRam.SetMode(Mode.Lava, 0); + #endregion + } + else { + #region beam + notification.message = "using [fire ray]"; + CwRam.SetMode(Mode.FireRay, 0); + #endregion + } + break; + #endregion + case EntityClass.Ranger when spec: + #region scout + if (hotkey == HotkeyID.CtrlSpace) { + #region shrapnel + notification.message = "using [shrapnel] bleeding test"; + var specialMove = new SpecialMove() { + Guid = BridgeCore.guid, + Id = SpecialMoveID.Shrapnel, + }; + BridgeCore.SendUDP(specialMove.data); + #endregion + } + else { + #region smoke bomb + notification.message = "using [smoke bomb]"; + var specialMove = new SpecialMove() { + Guid = BridgeCore.guid, + Id = SpecialMoveID.SmokeBomb, + }; + BridgeCore.SendUDP(specialMove.data); + + var fakeSmoke = new ServerUpdate(); + fakeSmoke.particles.Add(new ServerUpdate.Particle() { + count = 1000, + spread = 5f, + type = ParticleType.NoGravity, + size = 0.3f, + velocity = new Resources.Utilities.FloatVector(), + color = new Resources.Utilities.FloatVector() { + x = 1f, + y = 1f, + z = 1f + }, + alpha = 1f, + position = BridgeCore.dynamicEntities[specialMove.Guid].position + }); + BridgeCore.SendToClient(fakeSmoke); + #endregion + } + break; + #endregion + case EntityClass.Ranger: + #region sniper + if (hotkey == HotkeyID.CtrlSpace) { + #region cursed arrow + //TODO + notification.message = "TODO: [cursed arrow]"; + #endregion + } + else { + #region arrow rain + //TODO + notification.message = "TODO: [arrow rain]"; + //const int rainSize = 7; + //for (int x = 0; x < rainSize; x++) { + // for (int y = 0; y < rainSize; y++) { + // var projectile = new Projectile() { + // Scale = 1f, + // Type = ProjectileType.Arrow, + // Source = guid, + // Velocity = new FloatVector() { x = 0, y = 0, z = -1f }, + // Position = new LongVector() { + // x = 0x8020800000,//dynamicEntities[guid].position.x + (long)((dynamicEntities[guid].rayHit.x + x - rainSize / 2) * 0x10000), + // y = 0x8020800000,//dynamicEntities[guid].position.y + (long)((dynamicEntities[guid].rayHit.y + y - rainSize / 2) * 0x10000), + // z = 0x01000000,//dynamicEntities[guid].position.z + (long)((dynamicEntities[guid].rayHit.z + 10) * 0x10000), + // } + // }; + // SendUDP(projectile.data); + // ProcessDatagram(projectile.data); + // } + //} + #endregion + } + break; + #endregion + } + CwRam.memory.WriteInt(CwRam.EntityStart + 0x1164, 3);//mana cubes + BridgeCore.SendToClient(notification); + } + } +} diff --git a/Bridge/FormMain.cs b/Bridge/FormMain.cs index 7c31963..f2f611d 100644 --- a/Bridge/FormMain.cs +++ b/Bridge/FormMain.cs @@ -1,4 +1,5 @@ -using ReadWriteProcessMemory; +using Bridge.Extensions; +using ReadWriteProcessMemory; using System; using System.Diagnostics; using System.Drawing; @@ -12,8 +13,8 @@ public partial class FormMain : Form { public FormRegister register = new FormRegister(); public FormChat chat = new FormChat(); public FormRankings rankings = new FormRankings(); + public KeyboardHook keyboardHook; private bool processAttached = false; - private KeyboardHook keyboardHook; public FormMain(string[]args) { InitializeComponent(); @@ -24,9 +25,10 @@ private void FormMain_Shown(object sender, EventArgs e) { chat.Left = Left + Width; BridgeCore.form = this; CwRam.formMain = this; + keyboardHook = new KeyboardHook(); new Thread(BridgeCore.ListenFromClientTCP).Start(); new Thread(BridgeCore.Connect).Start(); - keyboardHook = new KeyboardHook(); + ExtensionsCore.Init(); } private void timerSearchProcess_Tick(object sender, EventArgs e) { if (processAttached) { diff --git a/Bridge/KeyboardHook.cs b/Bridge/KeyboardHook.cs index 5b67069..c7b4d9c 100644 --- a/Bridge/KeyboardHook.cs +++ b/Bridge/KeyboardHook.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Runtime.InteropServices; -using System.Text; using System.Threading.Tasks; using System.Windows.Forms; @@ -92,25 +90,12 @@ private int KeybHookProc(int Code, int W, int L) { private Dictionary keyboardState = new Dictionary(); private void OnKey(Keys key, bool isDown) { if (GetForegroundWindow() != CwRam.memory.process.MainWindowHandle) return; - if (!keyboardState.ContainsKey(key)) keyboardState.Add(key, !isDown); if (keyboardState[key] == isDown) return; keyboardState[key] = isDown; - - if (!isDown) return;//temp fix to prevent activation on release - switch (key) { - case Keys.D4: - BridgeCore.OnHotkey(Resources.HotkeyID.CtrlSpace); - break; - case Keys.D5: - BridgeCore.OnHotkey(Resources.HotkeyID.SpecialMove2); - break; - case Keys.D0: - BridgeCore.OnHotkey(Resources.HotkeyID.TeleportToTown); - break; - default: - break; - } + KeyboardChanged?.Invoke(key, isDown); } + public delegate void KeyboardChangedEventHandler(Keys key, bool isDown); + public event KeyboardChangedEventHandler KeyboardChanged; } } diff --git a/Resources/Config.cs b/Resources/Config.cs index 3bc30fb..eb03c47 100644 --- a/Resources/Config.cs +++ b/Resources/Config.cs @@ -2,7 +2,7 @@ static public class Config { public const int mapseed = 8710; //hardcoded for now public const int bridgeVersion = 16; - public const string serverIP = "pb97.ddns.net";//temp + public const string serverIP = "localhost";//temp public const int serverPort = 12346; } } diff --git a/Resources/CubeworldNetworking b/Resources/CubeworldNetworking index b24405c..5323adb 160000 --- a/Resources/CubeworldNetworking +++ b/Resources/CubeworldNetworking @@ -1 +1 @@ -Subproject commit b24405c0d42a1384d3cce28cae56d7858fb568c5 +Subproject commit 5323adb8735c2b78d27fd2add8f4df54addbf546 From 33b28599c2d569a07558d9a1baf795067ca0cc2d Mon Sep 17 00:00:00 2001 From: LastExceed Date: Thu, 18 Oct 2018 11:39:21 +0200 Subject: [PATCH 12/13] fix possible server crash from enumeration changed --- Server/ServerCore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Server/ServerCore.cs b/Server/ServerCore.cs index 98b9cba..657a172 100644 --- a/Server/ServerCore.cs +++ b/Server/ServerCore.cs @@ -71,7 +71,7 @@ public static void SendUDP(byte[] data, Player target) { udpClient.Send(data, data.Length, target.RemoteEndPoint); } public static void BroadcastUDP(byte[] data, Player toSkip = null) { - foreach (var player in players) { + foreach (var player in players.ToList()) { if (player != toSkip) { SendUDP(data, player); } From 4f8fc3afc3c05e13ca25eaeabec56e2580db1315 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Fri, 19 Oct 2018 20:28:07 +0200 Subject: [PATCH 13/13] Implement Role System --- Resources/Enums.cs | 12 +++++++ Resources/Player.cs | 1 + Server/Database/User.cs | 1 + Server/Database/UserDatabase.cs | 20 +++++++++++ Server/Extensions/ChatCommands.cs | 13 +++++-- Server/Extensions/ConsoleCommands.cs | 53 ++++++++++++++++++++++++++++ Server/Program.cs | 6 ++-- Server/ServerCore.cs | 1 + 8 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 Server/Extensions/ConsoleCommands.cs diff --git a/Resources/Enums.cs b/Resources/Enums.cs index 4fc5fc0..50a073c 100644 --- a/Resources/Enums.cs +++ b/Resources/Enums.cs @@ -58,4 +58,16 @@ public enum BridgeStatus : byte { LoggedIn, Playing, } + public enum RoleID : byte + { + Default, + Vip, + Mod, + Admin + } + public enum PromoteResponse : byte + { + Success, + InvalidTarget + } } diff --git a/Resources/Player.cs b/Resources/Player.cs index 40f9fae..c85b017 100644 --- a/Resources/Player.cs +++ b/Resources/Player.cs @@ -9,6 +9,7 @@ public class Player { public BinaryWriter writer; public BinaryReader reader; public EntityUpdate entity; + public byte Permission; public ushort? tomb; public string MAC; public ushort lastTarget; diff --git a/Server/Database/User.cs b/Server/Database/User.cs index 27d7baf..6608939 100644 --- a/Server/Database/User.cs +++ b/Server/Database/User.cs @@ -23,6 +23,7 @@ public User(string username, string email, string password) { this.Name = username; this.Email = email; this.PasswordHash = Hashing.Hash(password); + this.Permission = 0; } public bool VerifyPassword(string password) { diff --git a/Server/Database/UserDatabase.cs b/Server/Database/UserDatabase.cs index 44c887d..f09cd75 100644 --- a/Server/Database/UserDatabase.cs +++ b/Server/Database/UserDatabase.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using Resources; +using System; using System.Linq; namespace Server.Database { @@ -87,5 +88,24 @@ public void BanUser(string entityName, int ipAddress, string targetMac, string r Bans.Add(ban); SaveChanges(); } + public PromoteResponse PromoteUser(string entityName, RoleID roleId) + { + var user = Users.SingleOrDefault(x => x.Name == entityName); + if (user != null) + { + user.Permission = (byte)roleId; + SaveChanges(); + return PromoteResponse.Success; + } + else + { + return PromoteResponse.InvalidTarget; + } + } + public byte getRoleId(string entityName) + { + var user = Users.SingleOrDefault(x => x.Name == entityName); + return user.Permission; + } } } \ No newline at end of file diff --git a/Server/Extensions/ChatCommands.cs b/Server/Extensions/ChatCommands.cs index 56fab56..2ad170b 100644 --- a/Server/Extensions/ChatCommands.cs +++ b/Server/Extensions/ChatCommands.cs @@ -20,10 +20,12 @@ private static void ParseAsCommand(string message, Player source) { var command = parameters[0].ToLower(); switch (command) { case "kick": + break; case "btfo": + break; case "ban": #region ban - if (source.entity.name != "BLACKROCK") { + if (!minimumPermission(source,3)) { ServerCore.Notify(source, "no permission"); break; } @@ -53,7 +55,6 @@ private static void ParseAsCommand(string message, Player source) { break; #endregion case "bleeding": - break; case "time": #region time @@ -79,5 +80,13 @@ private static void ParseAsCommand(string message, Player source) { break; } } + private static Boolean minimumPermission(Player source,int roleId) + { + if(source.Permission >= roleId) + { + return true; + } + return false; + } } } diff --git a/Server/Extensions/ConsoleCommands.cs b/Server/Extensions/ConsoleCommands.cs new file mode 100644 index 0000000..35d847e --- /dev/null +++ b/Server/Extensions/ConsoleCommands.cs @@ -0,0 +1,53 @@ +using Resources; +using Server.Database; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Server.Extensions +{ + static class ConsoleCommands + { + public static void analyzeCommand(string consoleCommands) + { + var parameters = consoleCommands.Split(" "); + switch (parameters[0]) + { + case "promote": + if(parameters.Length == 3) + { + int role = int.Parse(parameters[2]); + if (0 <= role && role <= Enum.GetValues(typeof(RoleID)).Length - 1) + { + PromoteResponse response = ServerCore.userDatabase.PromoteUser(parameters[1], (RoleID)role); + if(response == PromoteResponse.Success) + { + var player = ServerCore.players.FirstOrDefault(x => x.entity?.name == parameters[1]); + if (player != null) + { + player.Permission = (byte)role; + } + Log.PrintLn(String.Format("User '{0}' promoted to role {1}!", parameters[1], parameters[2])); + } + else if(response == PromoteResponse.InvalidTarget) + { + Log.PrintLn(String.Format("Error : Invalid target")); + } + } + else + { + Log.PrintLn(String.Format("Error : RoleId out of Range")); + } + } + else + { + Log.PrintLn(String.Format("Syntax : promote [player] [roleId]")); + } + break; + case "default": + break; + } + } + } +} \ No newline at end of file diff --git a/Server/Program.cs b/Server/Program.cs index 2596c96..8b951fd 100644 --- a/Server/Program.cs +++ b/Server/Program.cs @@ -1,11 +1,13 @@ -using System; +using Server.Extensions; +using System; namespace Server { class Program { static void Main(string[] args) { ServerCore.Start(12346); while (true) { - Console.ReadLine(); + + ConsoleCommands.analyzeCommand(Console.ReadLine()); } } } diff --git a/Server/ServerCore.cs b/Server/ServerCore.cs index 657a172..ada329e 100644 --- a/Server/ServerCore.cs +++ b/Server/ServerCore.cs @@ -125,6 +125,7 @@ private static void ProcessPacket(byte packetID, Player source) { guid = AssignGuid(), name = username, }; + source.Permission = userDatabase.getRoleId(username); source.writer.Write((ushort)source.entity.guid); source.writer.Write(Config.mapseed);