New changes!

This commit is contained in:
MrOkiDoki 2023-08-14 12:43:58 +03:00
parent aea0de1eb6
commit bbfbabe2d9
10 changed files with 433 additions and 167 deletions

View File

@ -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);
}
}
}

View File

@ -0,0 +1,7 @@
namespace BattleBitAPI.Common
{
public enum LeaningSide
{
Left, None, Right
}
}

View File

@ -0,0 +1,12 @@
namespace BattleBitAPI.Common
{
public enum LoadoutIndex : byte
{
Primary = 0,
Secondary = 1,
FirstAid = 2,
LightGadget = 3,
HeavyGadget = 4,
Throwable = 5,
}
}

View File

@ -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,
}
}

View File

@ -8,21 +8,40 @@ namespace BattleBitAPI
{
public class Player<TPlayer> where TPlayer : Player<TPlayer>
{
public ulong SteamID { get; internal set; }
public string Name { get; internal set; }
public IPAddress IP { get; internal set; }
public GameServer<TPlayer> 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<TPlayer> 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<TPlayer>(Player<TPlayer>.Internal @internal) where TPlayer : Player<TPlayer>
{
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<TPlayer> 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();
}
}
}
}

View File

@ -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<TPlayer> ServerSettings => mInternal.ServerSettings;
@ -264,15 +264,18 @@ namespace BattleBitAPI.Server
{
return true;
}
public virtual async Task<PlayerStats> 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<bool> OnPlayerRequestingToChangeRole(TPlayer player, GameRole role)
public virtual async Task<bool> OnPlayerRequestingToChangeRole(TPlayer player, GameRole requestedRole)
{
return true;
}
public virtual async Task<bool> 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<TPlayer> 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<TPlayer> 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<TPlayer> 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<TPlayer> 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<TPlayer> 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;

View File

@ -1,4 +1,6 @@
namespace BattleBitAPI.Server
using BattleBitAPI.Common;
namespace BattleBitAPI.Server
{
public class GamemodeRotation<TPlayer> where TPlayer : Player<TPlayer>
{
@ -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()
{

View File

@ -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()
{

View File

@ -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
/// </remarks>
public Func<GameServer<TPlayer>, Task> OnGameServerDisconnected { get; set; }
/// <summary>
/// Fired when a new instance of game server created.
/// </summary>
///
/// <remarks>
/// GameServer: Game server that has been just created.<br/>
/// </remarks>
public Func<GameServer<TPlayer>, Task> OnCreatingGameServerInstance { get; set; }
/// <summary>
/// Fired when a new instance of player instance created.
/// </summary>
///
/// <remarks>
/// TPlayer: The player instance that was created<br/>
/// </remarks>
public Func<TPlayer, Task> OnCreatingPlayerInstance { get; set; }
// --- Private ---
private TcpListener mSocket;
private Dictionary<ulong, (TGameServer server, GameServer<TPlayer>.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<TPlayer>)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<TPlayer>)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<TPlayer>.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<TPlayer>)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<TPlayer>)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<TPlayer, TGameServer> where TPlayer : Player<TPlayer> where TGameServer : GameServer<TPlayer>
{
private Dictionary<ulong, (TGameServer, GameServer<TPlayer>.Internal)> mGameServerInstances;
private Dictionary<ulong, TPlayer> mPlayerInstances;
private Dictionary<ulong, (TPlayer, Player<TPlayer>.Internal)> mPlayerInstances;
public mInstances()
{
this.mGameServerInstances = new Dictionary<ulong, (TGameServer, GameServer<TPlayer>.Internal)>(64);
this.mPlayerInstances = new Dictionary<ulong, TPlayer>(1024 * 16);
this.mPlayerInstances = new Dictionary<ulong, (TPlayer, Player<TPlayer>.Internal)>(1024 * 16);
}
public TGameServer GetServerInstance(ulong hash, out GameServer<TPlayer>.Internal @internal)
public TGameServer GetServerInstance(ulong hash, out bool isNew, out GameServer<TPlayer>.Internal @internal)
{
lock (mGameServerInstances)
{
if (mGameServerInstances.TryGetValue(hash, out var data))
{
@internal = data.Item2;
isNew = false;
return data.Item1;
}
@internal = new GameServer<TPlayer>.Internal();
TGameServer gameServer = GameServer<TPlayer>.CreateInstance<TGameServer>(@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<TPlayer>.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<TPlayer>();
player.OnCreated();
mPlayerInstances.Add(steamID, player);
return player;
@internal = new Player<TPlayer>.Internal();
var pplayer = Player<TPlayer>.CreateInstance(@internal);
isNew = true;
mPlayerInstances.Add(steamID, (pplayer, @internal));
return pplayer;
}
}
public Player<TPlayer>.Internal GetPlayerInternals(ulong steamID)
{
lock (mPlayerInstances)
return mPlayerInstances[steamID].Item2;
}
}
}
}

View File

@ -13,101 +13,23 @@ class Program
Thread.Sleep(-1);
}
}
class MyPlayer : Player<MyPlayer>
{
public bool IsZombie;
}
class MyGameServer : GameServer<MyPlayer>
{
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<MyPlayer> 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<OnPlayerSpawnArguments> 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);
}
}
}