diff --git a/BattleBitAPI/Common/Arguments/PlayerJoiningArgument.cs b/BattleBitAPI/Common/Arguments/PlayerJoiningArgument.cs new file mode 100644 index 0000000..1cd9302 --- /dev/null +++ b/BattleBitAPI/Common/Arguments/PlayerJoiningArgument.cs @@ -0,0 +1,18 @@ +using System; + +namespace BattleBitAPI.Common +{ + public class PlayerJoiningArguments + { + public PlayerStats Stats; + public Team Team; + public Squads Squad; + + public void Write(BattleBitAPI.Common.Serialization.Stream ser) + { + this.Stats.Write(ser); + ser.Write((byte)this.Team); + ser.Write((byte)this.Squad); + } + } +} diff --git a/BattleBitAPI/Common/Enums/LeaningSide.cs b/BattleBitAPI/Common/Enums/LeaningSide.cs new file mode 100644 index 0000000..c44d82b --- /dev/null +++ b/BattleBitAPI/Common/Enums/LeaningSide.cs @@ -0,0 +1,7 @@ +namespace BattleBitAPI.Common +{ + public enum LeaningSide + { + Left, None, Right + } +} diff --git a/BattleBitAPI/Common/Enums/LoadoutIndex.cs b/BattleBitAPI/Common/Enums/LoadoutIndex.cs new file mode 100644 index 0000000..1737960 --- /dev/null +++ b/BattleBitAPI/Common/Enums/LoadoutIndex.cs @@ -0,0 +1,12 @@ +namespace BattleBitAPI.Common +{ + public enum LoadoutIndex : byte + { + Primary = 0, + Secondary = 1, + FirstAid = 2, + LightGadget = 3, + HeavyGadget = 4, + Throwable = 5, + } +} diff --git a/BattleBitAPI/Networking/NetworkCommuncation.cs b/BattleBitAPI/Networking/NetworkCommuncation.cs index 949f312..1927eb8 100644 --- a/BattleBitAPI/Networking/NetworkCommuncation.cs +++ b/BattleBitAPI/Networking/NetworkCommuncation.cs @@ -20,7 +20,7 @@ PlayerDisconnected = 51, OnPlayerTypedMessage = 52, OnPlayerKilledAnotherPlayer = 53, - GetPlayerStats = 54, + OnPlayerJoining = 54, SavePlayerStats = 55, OnPlayerAskingToChangeRole = 56, OnPlayerChangedRole = 57, @@ -34,5 +34,7 @@ NotifyNewMapRotation = 65, NotifyNewGamemodeRotation = 66, NotifyNewRoundState = 67, + OnPlayerAskingToChangeTeam = 68, + GameTick = 69, } } diff --git a/BattleBitAPI/Player.cs b/BattleBitAPI/Player.cs index 0153072..2c07f18 100644 --- a/BattleBitAPI/Player.cs +++ b/BattleBitAPI/Player.cs @@ -8,21 +8,40 @@ namespace BattleBitAPI { public class Player where TPlayer : Player { - public ulong SteamID { get; internal set; } - public string Name { get; internal set; } - public IPAddress IP { get; internal set; } - public GameServer GameServer { get; internal set; } - public GameRole Role { get; internal set; } - public Team Team { get; internal set; } - public Squads Squad { get; internal set; } - public bool IsAlive { get; internal set; } - public PlayerLoadout CurrentLoadout { get; internal set; } = new PlayerLoadout(); - public PlayerWearings CurrentWearings { get; internal set; } = new PlayerWearings(); + private Internal mInternal; + // ---- Variables ---- + public ulong SteamID => mInternal.SteamID; + public string Name => mInternal.Name; + public IPAddress IP => mInternal.IP; + public GameServer GameServer => mInternal.GameServer; + public GameRole Role => mInternal.Role; + public Team Team => mInternal.Team; + public Squads Squad => mInternal.Squad; + public bool InSquad => mInternal.Squad != Squads.NoSquad; + public int PingMs => mInternal.PingMs; + + public float HP => mInternal.HP; + public bool IsAlive => mInternal.HP >= 0f; + public bool IsUp => mInternal.HP > 0f; + public bool IsDown => mInternal.HP == 0f; + public bool IsDead => mInternal.HP == -1f; + + public Vector3 Position => mInternal.Position; + public PlayerStand Standing => mInternal.Standing; + public LeaningSide Leaning => mInternal.Leaning; + public LoadoutIndex CurrentLoadoutIndex => mInternal.CurrentLoadoutIndex; + public bool InVehicle => mInternal.InVehicle; + public bool IsBleeding => mInternal.IsBleeding; + public PlayerLoadout CurrentLoadout => mInternal.CurrentLoadout; + public PlayerWearings CurrentWearings => mInternal.CurrentWearings; + + // ---- Events ---- public virtual void OnCreated() { } + public virtual async Task OnConnected() { @@ -34,12 +53,29 @@ namespace BattleBitAPI public virtual async Task OnDied() { + } + public virtual async Task OnChangedTeam() + { + + } + public virtual async Task OnChangedRole(GameRole newRole) + { + + } + public virtual async Task OnJoinedSquad(Squads newSquad) + { + + } + public virtual async Task OnLeftSquad(Squads oldSquad) + { + } public virtual async Task OnDisconnected() { } + // ---- Functions ---- public void Kick(string reason = "") { this.GameServer.Kick(this, reason); @@ -52,6 +88,10 @@ namespace BattleBitAPI { this.GameServer.ChangeTeam(this); } + public void ChangeTeam(Team team) + { + this.GameServer.ChangeTeam(this, team); + } public void KickFromSquad() { this.GameServer.KickFromSquad(this); @@ -72,6 +112,10 @@ namespace BattleBitAPI { this.GameServer.MessageToPlayer(this, msg); } + public void Message(string msg, float fadeoutTime) + { + this.GameServer.MessageToPlayer(this, msg, fadeoutTime); + } public void SetNewRole(GameRole role) { this.GameServer.SetRoleTo(this, role); @@ -116,7 +160,7 @@ namespace BattleBitAPI { GameServer.SetFallDamageMultiplier(this, value); } - public void SetPrimaryWeapon(WeaponItem item, int extraMagazines,bool clear=false) + public void SetPrimaryWeapon(WeaponItem item, int extraMagazines, bool clear = false) { GameServer.SetPrimaryWeapon(this, item, extraMagazines, clear); } @@ -140,9 +184,57 @@ namespace BattleBitAPI { GameServer.SetThrowable(this, item, extra, clear); } + + // ---- Static ---- + public static TPlayer CreateInstance(Player.Internal @internal) where TPlayer : Player + { + TPlayer player = (TPlayer)Activator.CreateInstance(typeof(TPlayer)); + player.mInternal = @internal; + return player; + } + + // ---- Overrides ---- public override string ToString() { return this.Name + " (" + this.SteamID + ")"; } + + // ---- Internal ---- + public class Internal + { + public ulong SteamID; + public string Name; + public IPAddress IP; + public GameServer GameServer; + public GameRole Role; + public Team Team; + public Squads Squad; + public int PingMs = 999; + + public bool IsAlive; + public float HP; + public Vector3 Position; + public PlayerStand Standing; + public LeaningSide Leaning; + public LoadoutIndex CurrentLoadoutIndex; + public bool InVehicle; + public bool IsBleeding; + public PlayerLoadout CurrentLoadout; + public PlayerWearings CurrentWearings; + + public void OnDie() + { + this.IsAlive = false; + this.HP = -1f; + this.Position = default; + this.Standing = PlayerStand.Standing; + this.Leaning = LeaningSide.None; + this.CurrentLoadoutIndex = LoadoutIndex.Primary; + this.InVehicle = false; + this.IsBleeding = false; + this.CurrentLoadout = new PlayerLoadout(); + this.CurrentWearings = new PlayerWearings(); + } + } } } diff --git a/BattleBitAPI/Server/GameServer.cs b/BattleBitAPI/Server/GameServer.cs index 144bf6a..e3a28d6 100644 --- a/BattleBitAPI/Server/GameServer.cs +++ b/BattleBitAPI/Server/GameServer.cs @@ -25,9 +25,9 @@ namespace BattleBitAPI.Server public string Map => mInternal.Map; public MapSize MapSize => mInternal.MapSize; public MapDayNight DayNight => mInternal.DayNight; - public int CurrentPlayers => mInternal.CurrentPlayers; - public int InQueuePlayers => mInternal.InQueuePlayers; - public int MaxPlayers => mInternal.MaxPlayers; + public int CurrentPlayerCount => mInternal.CurrentPlayerCount; + public int InQueuePlayerCount => mInternal.InQueuePlayerCount; + public int MaxPlayerCount => mInternal.MaxPlayerCount; public string LoadingScreenText => mInternal.LoadingScreenText; public string ServerRulesText => mInternal.ServerRulesText; public ServerSettings ServerSettings => mInternal.ServerSettings; @@ -264,15 +264,18 @@ namespace BattleBitAPI.Server { return true; } - public virtual async Task OnGetPlayerStats(ulong steamID, PlayerStats officialStats) + public virtual async Task OnPlayerJoiningToServer(ulong steamID, PlayerJoiningArguments args) { - return officialStats; } public virtual async Task OnSavePlayerStats(ulong steamID, PlayerStats stats) { } - public virtual async Task OnPlayerRequestingToChangeRole(TPlayer player, GameRole role) + public virtual async Task OnPlayerRequestingToChangeRole(TPlayer player, GameRole requestedRole) + { + return true; + } + public virtual async Task OnPlayerRequestingToChangeTeam(TPlayer player, Team requestedTeam) { return true; } @@ -417,6 +420,17 @@ namespace BattleBitAPI.Server { ChangeTeam(player.SteamID); } + public void ChangeTeam(ulong steamID, Team team) + { + if (team == Team.TeamA) + ExecuteCommand("changeteam " + steamID + " a"); + else if (team == Team.TeamB) + ExecuteCommand("changeteam " + steamID + " b"); + } + public void ChangeTeam(Player player, Team team) + { + ChangeTeam(player.SteamID, team); + } public void KickFromSquad(ulong steamID) { ExecuteCommand("squadkick " + steamID); @@ -425,13 +439,13 @@ namespace BattleBitAPI.Server { KickFromSquad(player.SteamID); } - public void DisbandPlayerSSquad(ulong steamID) + public void DisbandPlayerSquad(ulong steamID) { ExecuteCommand("squaddisband " + steamID); } public void DisbandPlayerCurrentSquad(Player player) { - DisbandPlayerSSquad(player.SteamID); + DisbandPlayerSquad(player.SteamID); } public void PromoteSquadLeader(ulong steamID) { @@ -457,6 +471,14 @@ namespace BattleBitAPI.Server { MessageToPlayer(player.SteamID, msg); } + public void MessageToPlayer(ulong steamID, string msg, float fadeOutTime) + { + ExecuteCommand("msgf " + steamID + " " + fadeOutTime + " " + msg); + } + public void MessageToPlayer(Player player, string msg, float fadeOutTime) + { + MessageToPlayer(player.SteamID, msg, fadeOutTime); + } public void SetRoleTo(ulong steamID, GameRole role) { ExecuteCommand("setrole " + steamID + " " + role); @@ -664,7 +686,7 @@ namespace BattleBitAPI.Server } public void SetThrowable(Player player, string tool, int extra, bool clear = false) { - SetThrowable(player.SteamID, tool, extra,clear); + SetThrowable(player.SteamID, tool, extra, clear); } // ---- Closing ---- @@ -727,9 +749,9 @@ namespace BattleBitAPI.Server public string Map; public MapSize MapSize; public MapDayNight DayNight; - public int CurrentPlayers; - public int InQueuePlayers; - public int MaxPlayers; + public int CurrentPlayerCount; + public int InQueuePlayerCount; + public int MaxPlayerCount; public string LoadingScreenText; public string ServerRulesText; public ServerSettings ServerSettings; @@ -814,9 +836,9 @@ namespace BattleBitAPI.Server this.Map = map; this.MapSize = mapSize; this.DayNight = dayNight; - this.CurrentPlayers = currentPlayers; - this.InQueuePlayers = inQueuePlayers; - this.MaxPlayers = maxPlayers; + this.CurrentPlayerCount = currentPlayers; + this.InQueuePlayerCount = inQueuePlayers; + this.MaxPlayerCount = maxPlayers; this.LoadingScreenText = loadingScreenText; this.ServerRulesText = serverRulesText; diff --git a/BattleBitAPI/Server/Internal/GamemodeRotation.cs b/BattleBitAPI/Server/Internal/GamemodeRotation.cs index 2341290..999b11b 100644 --- a/BattleBitAPI/Server/Internal/GamemodeRotation.cs +++ b/BattleBitAPI/Server/Internal/GamemodeRotation.cs @@ -1,4 +1,6 @@ -namespace BattleBitAPI.Server +using BattleBitAPI.Common; + +namespace BattleBitAPI.Server { public class GamemodeRotation where TPlayer : Player { @@ -34,6 +36,27 @@ mResources.IsDirtyGamemodeRotation = true; return true; } + public void SetRotation(params string[] gamemodes) + { + lock (mResources._GamemodeRotation) + { + mResources._GamemodeRotation.Clear(); + foreach (var item in gamemodes) + mResources._GamemodeRotation.Add(item); + } + mResources.IsDirtyGamemodeRotation = true; + } + public void ClearRotation() + { + lock (mResources._GamemodeRotation) + { + if (mResources._GamemodeRotation.Count == 0) + return; + + mResources._GamemodeRotation.Clear(); + } + mResources.IsDirtyGamemodeRotation = true; + } public void Reset() { diff --git a/BattleBitAPI/Server/Internal/MapRotation.cs b/BattleBitAPI/Server/Internal/MapRotation.cs index e59dfec..e68d321 100644 --- a/BattleBitAPI/Server/Internal/MapRotation.cs +++ b/BattleBitAPI/Server/Internal/MapRotation.cs @@ -40,6 +40,27 @@ mResources.IsDirtyMapRotation = true; return true; } + public void SetRotation(params string[] maps) + { + lock (mResources._MapRotation) + { + mResources._MapRotation.Clear(); + foreach (var item in maps) + mResources._MapRotation.Add(item); + } + mResources.IsDirtyMapRotation = true; + } + public void ClearRotation() + { + lock (mResources._MapRotation) + { + if (mResources._MapRotation.Count == 0) + return; + + mResources._MapRotation.Clear(); + } + mResources.IsDirtyMapRotation = true; + } public void Reset() { diff --git a/BattleBitAPI/Server/ServerListener.cs b/BattleBitAPI/Server/ServerListener.cs index 8604aa4..a7a750c 100644 --- a/BattleBitAPI/Server/ServerListener.cs +++ b/BattleBitAPI/Server/ServerListener.cs @@ -1,7 +1,9 @@ -using System.Net; +using System.Diagnostics; +using System.Net; using System.Net.Security; using System.Net.Sockets; using System.Numerics; +using System.Xml; using BattleBitAPI.Common; using BattleBitAPI.Common.Extentions; using BattleBitAPI.Common.Serialization; @@ -59,6 +61,24 @@ namespace BattleBitAPI.Server /// public Func, Task> OnGameServerDisconnected { get; set; } + /// + /// Fired when a new instance of game server created. + /// + /// + /// + /// GameServer: Game server that has been just created.
+ ///
+ public Func, Task> OnCreatingGameServerInstance { get; set; } + + /// + /// Fired when a new instance of player instance created. + /// + /// + /// + /// TPlayer: The player instance that was created
+ ///
+ public Func OnCreatingPlayerInstance { get; set; } + // --- Private --- private TcpListener mSocket; private Dictionary.Internal resources)> mActiveConnections; @@ -91,7 +111,7 @@ namespace BattleBitAPI.Server } public void Start(int port) { - Start(IPAddress.Loopback, port); + Start(IPAddress.Any, port); } // --- Stopping --- @@ -325,7 +345,7 @@ namespace BattleBitAPI.Server } var hash = ((ulong)gamePort << 32) | (ulong)ip.ToUInt(); - server = this.mInstanceDatabase.GetServerInstance(hash, out resources); + server = this.mInstanceDatabase.GetServerInstance(hash, out bool isNew, out resources); resources.Set( this.mExecutePackage, client, @@ -498,23 +518,37 @@ namespace BattleBitAPI.Server wearings.Read(readStream); } - TPlayer player = mInstanceDatabase.GetPlayerInstance(steamid); - player.SteamID = steamid; - player.Name = username; - player.IP = new IPAddress(ipHash); - player.GameServer = (GameServer)server; - player.Team = team; - player.Squad = squad; - player.Role = role; - player.IsAlive = isAlive; - player.CurrentLoadout = loadout; - player.CurrentWearings = wearings; + TPlayer player = mInstanceDatabase.GetPlayerInstance(steamid, out bool isNewClient, out var playerInternal); + playerInternal.SteamID = steamid; + playerInternal.Name = username; + playerInternal.IP = new IPAddress(ipHash); + playerInternal.GameServer = (GameServer)server; + playerInternal.Team = team; + playerInternal.Squad = squad; + playerInternal.Role = role; + playerInternal.IsAlive = isAlive; + playerInternal.CurrentLoadout = loadout; + playerInternal.CurrentWearings = wearings; + + if (isNewClient) + { + if (this.OnCreatingPlayerInstance != null) + this.OnCreatingPlayerInstance(player); + } + resources.AddPlayer(player); } //Send accepted notification. networkStream.WriteByte((byte)NetworkCommuncation.Accepted); + + if (isNew) + { + if (this.OnCreatingGameServerInstance != null) + this.OnCreatingGameServerInstance(server); + } + } } } @@ -575,9 +609,9 @@ namespace BattleBitAPI.Server client.SendBufferSize = Const.MaxNetworkPackageSize; //Join to main server loop. - await mHandleGameServer(server); + await mHandleGameServer(server, resources); } - private async Task mHandleGameServer(TGameServer server) + private async Task mHandleGameServer(TGameServer server, GameServer.Internal @internal) { bool isTicking = false; @@ -632,19 +666,25 @@ namespace BattleBitAPI.Server Squads squad = (Squads)stream.ReadInt8(); GameRole role = (GameRole)stream.ReadInt8(); - TPlayer player = mInstanceDatabase.GetPlayerInstance(steamID); - player.SteamID = steamID; - player.Name = username; - player.IP = new IPAddress(ip); - player.GameServer = (GameServer)server; + TPlayer player = mInstanceDatabase.GetPlayerInstance(steamID, out bool isNewClient, out var playerInternal); + playerInternal.SteamID = steamID; + playerInternal.Name = username; + playerInternal.IP = new IPAddress(ip); + playerInternal.GameServer = (GameServer)server; - player.Team = team; - player.Squad = squad; - player.Role = role; + playerInternal.Team = team; + playerInternal.Squad = squad; + playerInternal.Role = role; + + if (isNewClient) + { + if (this.OnCreatingPlayerInstance != null) + this.OnCreatingPlayerInstance(player); + } resources.AddPlayer(player); - server.OnPlayerConnected(player); player.OnConnected(); + server.OnPlayerConnected(player); } } break; @@ -661,8 +701,8 @@ namespace BattleBitAPI.Server if (exist) { - server.OnPlayerDisconnected((TPlayer)player); player.OnDisconnected(); + server.OnPlayerDisconnected((TPlayer)player); } } break; @@ -738,7 +778,7 @@ namespace BattleBitAPI.Server break; } - case NetworkCommuncation.GetPlayerStats: + case NetworkCommuncation.OnPlayerJoining: { if (stream.CanRead(8 + 2)) { @@ -746,14 +786,22 @@ namespace BattleBitAPI.Server var stats = new PlayerStats(); stats.Read(stream); + async Task mHandle() { - stats = await server.OnGetPlayerStats(steamID, stats); + var args = new PlayerJoiningArguments() + { + Stats = stats, + Squad = Squads.NoSquad, + Team = Team.None + }; + + await server.OnPlayerJoiningToServer(steamID, args); using (var response = Common.Serialization.Stream.Get()) { response.Write((byte)NetworkCommuncation.SendPlayerStats); response.Write(steamID); - stats.Write(response); + args.Write(response); server.WriteToSocket(response); } } @@ -804,7 +852,10 @@ namespace BattleBitAPI.Server if (resources.TryGetPlayer(steamID, out var client)) { - client.Role = role; + var @internal = mInstanceDatabase.GetPlayerInternals(steamID); + @internal.Role = role; + + client.OnChangedRole(role); server.OnPlayerChangedRole((TPlayer)client, role); } } @@ -819,7 +870,10 @@ namespace BattleBitAPI.Server if (resources.TryGetPlayer(steamID, out var client)) { - client.Squad = squad; + var @internal = mInstanceDatabase.GetPlayerInternals(steamID); + @internal.Squad = squad; + + client.OnJoinedSquad(squad); server.OnPlayerJoinedSquad((TPlayer)client, squad); } } @@ -833,14 +887,21 @@ namespace BattleBitAPI.Server if (resources.TryGetPlayer(steamID, out var client)) { + var @internal = mInstanceDatabase.GetPlayerInternals(steamID); + var oldSquad = client.Squad; var oldRole = client.Role; - client.Squad = Squads.NoSquad; - client.Role = GameRole.Assault; + @internal.Squad = Squads.NoSquad; + @internal.Role = GameRole.Assault; + client.OnLeftSquad(oldSquad); server.OnPlayerLeftSquad((TPlayer)client, oldSquad); + if (oldRole != GameRole.Assault) + { + client.OnChangedRole(GameRole.Assault); server.OnPlayerChangedRole((TPlayer)client, GameRole.Assault); + } } } break; @@ -854,7 +915,11 @@ namespace BattleBitAPI.Server if (resources.TryGetPlayer(steamID, out var client)) { - client.Team = team; + var @internal = mInstanceDatabase.GetPlayerInternals(steamID); + + @internal.Team = team; + + client.OnChangedTeam(); server.OnPlayerChangeTeam((TPlayer)client, team); } } @@ -915,18 +980,20 @@ namespace BattleBitAPI.Server { if (stream.CanRead(8 + 2)) { - ulong reporter = stream.ReadUInt64(); - if (resources.TryGetPlayer(reporter, out var client)) + ulong steamID = stream.ReadUInt64(); + if (resources.TryGetPlayer(steamID, out var client)) { + var @internal = mInstanceDatabase.GetPlayerInternals(steamID); + var loadout = new PlayerLoadout(); loadout.Read(stream); - client.CurrentLoadout = loadout; + @internal.CurrentLoadout = loadout; var wearings = new PlayerWearings(); wearings.Read(stream); - client.CurrentWearings = wearings; + @internal.CurrentWearings = wearings; - client.IsAlive = true; + @internal.IsAlive = true; client.OnSpawned(); server.OnPlayerSpawned((TPlayer)client); @@ -938,12 +1005,11 @@ namespace BattleBitAPI.Server { if (stream.CanRead(8)) { - ulong reporter = stream.ReadUInt64(); - if (resources.TryGetPlayer(reporter, out var client)) + ulong steamid = stream.ReadUInt64(); + if (resources.TryGetPlayer(steamid, out var client)) { - client.CurrentLoadout = new PlayerLoadout(); - client.CurrentWearings = new PlayerWearings(); - client.IsAlive = false; + var @internal = mInstanceDatabase.GetPlayerInternals(steamid); + @internal.OnDie(); client.OnDied(); server.OnPlayerDied((TPlayer)client); @@ -1007,6 +1073,74 @@ namespace BattleBitAPI.Server } break; } + case NetworkCommuncation.OnPlayerAskingToChangeTeam: + { + if (stream.CanRead(8 + 1)) + { + ulong steamID = stream.ReadUInt64(); + Team team = (Team)stream.ReadInt8(); + + if (resources.TryGetPlayer(steamID, out var client)) + { + async Task mHandle() + { + bool accepted = await server.OnPlayerRequestingToChangeTeam((TPlayer)client, team); + if (accepted) + server.ChangeTeam(steamID, team); + } + + mHandle(); + } + } + break; + } + case NetworkCommuncation.GameTick: + { + if (stream.CanRead(4 + 4 + 4)) + { + float decompressX = stream.ReadFloat(); + float decompressY = stream.ReadFloat(); + float decompressZ = stream.ReadFloat(); + + int playerCount = stream.ReadInt8(); + while (playerCount > 0) + { + playerCount--; + ulong steamID = stream.ReadUInt64(); + + //TODO, can compressed further later. + ushort com_posX = stream.ReadUInt16(); + ushort com_posY = stream.ReadUInt16(); + ushort com_posZ = stream.ReadUInt16(); + byte com_healt = stream.ReadInt8(); + PlayerStand standing = (PlayerStand)stream.ReadInt8(); + LeaningSide side = (LeaningSide)stream.ReadInt8(); + LoadoutIndex loadoutIndex = (LoadoutIndex)stream.ReadInt8(); + bool inSeat = stream.ReadBool(); + bool isBleeding = stream.ReadBool(); + ushort ping = stream.ReadUInt16(); + + var @internal = mInstanceDatabase.GetPlayerInternals(steamID); + if (@internal.IsAlive) + { + @internal.Position = new Vector3() + { + X = com_posX * decompressX, + Y = com_posY * decompressY, + Z = com_posZ * decompressZ, + }; + @internal.HP = (com_healt * 0.5f) - 1f; + @internal.Standing = standing; + @internal.Leaning = side; + @internal.CurrentLoadoutIndex = loadoutIndex; + @internal.InVehicle = inSeat; + @internal.IsBleeding = isBleeding; + @internal.PingMs = ping; + } + } + } + break; + } } } @@ -1056,44 +1190,57 @@ namespace BattleBitAPI.Server private class mInstances where TPlayer : Player where TGameServer : GameServer { private Dictionary.Internal)> mGameServerInstances; - private Dictionary mPlayerInstances; + private Dictionary.Internal)> mPlayerInstances; public mInstances() { this.mGameServerInstances = new Dictionary.Internal)>(64); - this.mPlayerInstances = new Dictionary(1024 * 16); + this.mPlayerInstances = new Dictionary.Internal)>(1024 * 16); } - public TGameServer GetServerInstance(ulong hash, out GameServer.Internal @internal) + public TGameServer GetServerInstance(ulong hash, out bool isNew, out GameServer.Internal @internal) { lock (mGameServerInstances) { if (mGameServerInstances.TryGetValue(hash, out var data)) { @internal = data.Item2; + isNew = false; return data.Item1; } @internal = new GameServer.Internal(); TGameServer gameServer = GameServer.CreateInstance(@internal); + isNew = true; mGameServerInstances.Add(hash, (gameServer, @internal)); return gameServer; } } - public TPlayer GetPlayerInstance(ulong steamID) + public TPlayer GetPlayerInstance(ulong steamID, out bool isNew, out Player.Internal @internal) { lock (this.mPlayerInstances) { if (this.mPlayerInstances.TryGetValue(steamID, out var player)) - return player; + { + isNew = false; + @internal = player.Item2; + return player.Item1; + } - player = Activator.CreateInstance(); - player.OnCreated(); - mPlayerInstances.Add(steamID, player); - return player; + @internal = new Player.Internal(); + var pplayer = Player.CreateInstance(@internal); + + isNew = true; + mPlayerInstances.Add(steamID, (pplayer, @internal)); + return pplayer; } } + public Player.Internal GetPlayerInternals(ulong steamID) + { + lock (mPlayerInstances) + return mPlayerInstances[steamID].Item2; + } } } } diff --git a/Program.cs b/Program.cs index 3e3c094..8e1d8b8 100644 --- a/Program.cs +++ b/Program.cs @@ -13,101 +13,23 @@ class Program Thread.Sleep(-1); } + + } class MyPlayer : Player { - public bool IsZombie; } class MyGameServer : GameServer { - - public override async Task OnRoundStarted() - { - } - public override async Task OnRoundEnded() - { - } - - public override async Task OnPlayerConnected(MyPlayer player) - { - bool anyZombiePlayer = false; - foreach (var item in AllPlayers) - { - if (item.IsZombie) - { - anyZombiePlayer = true; - break; - } - } - - if (!anyZombiePlayer) - { - player.IsZombie = true; - player.Message("You are the zombie."); - player.Kill(); - } - } - - public override async Task OnAPlayerKilledAnotherPlayer(OnPlayerKillArguments args) - { - if (args.Victim.IsZombie) - { - args.Victim.IsZombie = false; - args.Victim.Message("You are no longer zombie"); - - AnnounceShort("Choosing new zombie in 5"); - await Task.Delay(1000); - AnnounceShort("Choosing new zombie in 4"); - await Task.Delay(1000); - AnnounceShort("Choosing new zombie in 3"); - await Task.Delay(1000); - AnnounceShort("Choosing new zombie in 2"); - await Task.Delay(1000); - AnnounceShort("Choosing new zombie in 1"); - await Task.Delay(1000); - - args.Killer.IsZombie = true; - args.Killer.SetHeavyGadget(Gadgets.SledgeHammer.ToString(), 0, true); - - var position = args.Killer.GetPosition(); - } - } - - - public override async Task OnPlayerSpawning(MyPlayer player, OnPlayerSpawnArguments request) - { - if (player.IsZombie) - { - request.Loadout.PrimaryWeapon = default; - request.Loadout.SecondaryWeapon = default; - request.Loadout.LightGadget = null; - request.Loadout.HeavyGadget = Gadgets.SledgeHammer; - request.Loadout.Throwable = null; - } - - return request; - } - public override async Task OnPlayerSpawned(MyPlayer player) - { - if(player.IsZombie) - { - player.SetRunningSpeedMultiplier(2f); - player.SetJumpMultiplier(2f); - player.SetFallDamageMultiplier(0f); - player.SetReceiveDamageMultiplier(0.1f); - player.SetGiveDamageMultiplier(4f); - } - } - - - public override async Task OnConnected() { - await Console.Out.WriteLineAsync("Current state: " + RoundSettings.State); - + ForceStartGame(); } - public override async Task OnGameStateChanged(GameState oldState, GameState newState) + public override async Task OnTick() { - await Console.Out.WriteLineAsync("State changed to -> " + newState); + foreach (var player in AllPlayers) + { + await Console.Out.WriteLineAsync(player + " : " + player.HP + " : " + player.Position); + } } }