Merge pull request #54 from MrOkiDoki/develop

Develop
This commit is contained in:
MrOkiDoki 2023-08-20 00:39:30 -07:00 committed by GitHub
commit 4f563a9b24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 772 additions and 151 deletions

View File

@ -2,6 +2,8 @@
{
public static class Const
{
public static string Version = "1.0.1v";
// ---- Networking ----
/// <summary>
/// Maximum data size for a single package. 4MB is default.

View File

@ -39,5 +39,6 @@
GameTick = 69,
OnPlayerGivenUp = 70,
OnPlayerRevivedAnother = 71,
OnSquadPointsChanged = 72,
}
}

View File

@ -0,0 +1,47 @@
namespace BattleBitAPI.Pooling
{
public class ItemPooling<TItem>
{
private Queue<ItemPooling<TItem>.List> mPool;
private int mDefaultCount;
public ItemPooling(int defaultCount)
{
this.mPool = new Queue<ItemPooling<TItem>.List>(6);
this.mDefaultCount = defaultCount;
}
public ItemPooling<TItem>.List Get()
{
lock (mPool)
{
if (mPool.Count > 0)
return mPool.Dequeue();
}
return new ItemPooling<TItem>.List(this, mDefaultCount);
}
public void Post(ItemPooling<TItem>.List item)
{
lock (mPool)
mPool.Enqueue(item);
}
public class List : IDisposable
{
private ItemPooling<TItem> mParent;
public List<TItem> ListItems;
public List(ItemPooling<TItem> parent, int count)
{
this.mParent = parent;
this.ListItems = new List<TItem>(count);
}
public void Dispose()
{
ListItems.Clear();
mParent.Post(this);
}
}
}
}

View File

@ -1,4 +1,6 @@
using System.Diagnostics;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Numerics;
@ -6,6 +8,7 @@ using System.Text;
using BattleBitAPI.Common;
using BattleBitAPI.Common.Extentions;
using BattleBitAPI.Networking;
using BattleBitAPI.Pooling;
using CommunityServerAPI.BattleBitAPI;
namespace BattleBitAPI.Server
@ -36,6 +39,32 @@ namespace BattleBitAPI.Server
public RoundSettings<TPlayer> RoundSettings => mInternal.RoundSettings;
public string TerminationReason => mInternal.TerminationReason;
public bool ReconnectFlag => mInternal.ReconnectFlag;
public IEnumerable<Squad<TPlayer>> TeamASquads
{
get
{
for (int i = 1; i < this.mInternal.TeamASquads.Length; i++)
yield return this.mInternal.TeamASquads[i];
}
}
public IEnumerable<Squad<TPlayer>> TeamBSquads
{
get
{
for (int i = 1; i < this.mInternal.TeamBSquads.Length; i++)
yield return this.mInternal.TeamBSquads[i];
}
}
public IEnumerable<Squad<TPlayer>> AllSquads
{
get
{
for (int i = 1; i < this.mInternal.TeamASquads.Length; i++)
yield return this.mInternal.TeamASquads[i];
for (int i = 1; i < this.mInternal.TeamBSquads.Length; i++)
yield return this.mInternal.TeamBSquads[i];
}
}
// ---- Private Variables ----
private Internal mInternal;
@ -240,15 +269,123 @@ namespace BattleBitAPI.Server
{
get
{
var list = new List<TPlayer>(this.mInternal.Players.Values.Count);
lock (this.mInternal.Players)
using (var list = this.mInternal.PlayerPool.Get())
{
foreach (var item in this.mInternal.Players.Values)
list.Add((TPlayer)item);
//Get A copy of players to our list
lock (this.mInternal.Players)
list.ListItems.AddRange(this.mInternal.Players.Values);
//Iterate our list.
for (int i = 0; i < list.ListItems.Count; i++)
yield return (TPlayer)list.ListItems[i];
}
return list;
}
}
public IEnumerable<TPlayer> AllTeamAPlayers
{
get
{
using (var list = this.mInternal.PlayerPool.Get())
{
//Get A copy of players to our list
lock (this.mInternal.Players)
list.ListItems.AddRange(this.mInternal.Players.Values);
//Iterate our list.
for (int i = 0; i < list.ListItems.Count; i++)
{
var item = list.ListItems[i];
if (item.Team == Team.TeamA)
yield return (TPlayer)item;
}
}
}
}
public IEnumerable<TPlayer> AllTeamBPlayers
{
get
{
using (var list = this.mInternal.PlayerPool.Get())
{
//Get A copy of players to our list
lock (this.mInternal.Players)
list.ListItems.AddRange(this.mInternal.Players.Values);
//Iterate our list.
for (int i = 0; i < list.ListItems.Count; i++)
{
var item = list.ListItems[i];
if (item.Team == Team.TeamB)
yield return (TPlayer)item;
}
}
}
}
public IEnumerable<TPlayer> PlayersOf(Team team)
{
using (var list = this.mInternal.PlayerPool.Get())
{
//Get A copy of players to our list
lock (this.mInternal.Players)
list.ListItems.AddRange(this.mInternal.Players.Values);
//Iterate our list.
for (int i = 0; i < list.ListItems.Count; i++)
{
var item = list.ListItems[i];
if (item.Team == team)
yield return (TPlayer)item;
}
}
}
public IEnumerable<TPlayer> SearchPlayerByName(string keyword)
{
keyword = keyword.ToLower().Replace(" ", "");
using (var list = this.mInternal.PlayerPool.Get())
{
//Get A copy of players to our list
lock (this.mInternal.Players)
list.ListItems.AddRange(this.mInternal.Players.Values);
//Iterate our list.
for (int i = 0; i < list.ListItems.Count; i++)
{
var item = list.ListItems[i];
if (item.Name.ToLower().Replace(" ", "").Contains(keyword))
yield return (TPlayer)item;
}
}
}
public IEnumerable<TPlayer> SearchPlayerByName(params string[] keywords)
{
for (int i = 0; i < keywords.Length; i++)
keywords[i] = keywords[i].ToLower().Replace(" ", "");
using (var list = this.mInternal.PlayerPool.Get())
{
//Get A copy of players to our list
lock (this.mInternal.Players)
list.ListItems.AddRange(this.mInternal.Players.Values);
//Iterate our list.
for (int i = 0; i < list.ListItems.Count; i++)
{
var item = list.ListItems[i];
var lowerName = item.Name.ToLower().Replace(" ", "");
for (int x = 0; x < keywords.Length; x++)
{
if (lowerName.Contains(keywords[x]))
{
yield return (TPlayer)item;
break;
}
}
}
}
}
public bool TryGetPlayer(ulong steamID, out TPlayer player)
{
lock (this.mInternal.Players)
@ -312,11 +449,11 @@ namespace BattleBitAPI.Server
{
}
public virtual async Task OnPlayerJoinedSquad(TPlayer player, Squads squad)
public virtual async Task OnPlayerJoinedSquad(TPlayer player, Squad<TPlayer> squad)
{
}
public virtual async Task OnPlayerLeftSquad(TPlayer player, Squads squad)
public virtual async Task OnPlayerLeftSquad(TPlayer player, Squad<TPlayer> squad)
{
}
@ -324,7 +461,11 @@ namespace BattleBitAPI.Server
{
}
public virtual async Task<OnPlayerSpawnArguments> OnPlayerSpawning(TPlayer player, OnPlayerSpawnArguments request)
public virtual async Task OnSquadPointsChanged(Squad<TPlayer> squad, int newPoints)
{
}
public virtual async Task<OnPlayerSpawnArguments?> OnPlayerSpawning(TPlayer player, OnPlayerSpawnArguments request)
{
return request;
}
@ -542,7 +683,7 @@ namespace BattleBitAPI.Server
SpawnPosition = position,
LookDirection = lookDirection,
SpawnStand = stand,
SpawnProtection = spawnProtection
SpawnProtection = spawnProtection,
};
//Respond back.
@ -584,6 +725,10 @@ namespace BattleBitAPI.Server
{
Heal(player.SteamID, heal);
}
public void SetSquadPointsOf(Team team, Squads squad, int points)
{
ExecuteCommand("setsquadpoints " + ((int)(team)) + " " + ((int)squad) + " " + points);
}
public void SetPrimaryWeapon(ulong steamID, WeaponItem item, int extraMagazines, bool clear = false)
{
@ -694,6 +839,31 @@ namespace BattleBitAPI.Server
SetThrowable(player.SteamID, tool, extra, clear);
}
// ---- Squads ----
public IEnumerable<TPlayer> IterateMembersOf(Squad<TPlayer> squad)
{
using (var list = this.mInternal.PlayerPool.Get())
{
var rsquad = this.mInternal.GetSquadInternal(squad);
//Get A copy of players to our list
lock (rsquad.Members)
list.ListItems.AddRange(rsquad.Members);
//Iterate our list.
for (int i = 0; i < list.ListItems.Count; i++)
yield return (TPlayer)list.ListItems[i];
}
}
public Squad<TPlayer> GetSquad(Team team, Squads name)
{
if (team == Team.TeamA)
return this.mInternal.TeamASquads[(int)name];
if (team == Team.TeamB)
return this.mInternal.TeamBSquads[(int)name];
return null;
}
// ---- Closing ----
public void CloseConnection(string additionInfo = "")
{
@ -764,6 +934,11 @@ namespace BattleBitAPI.Server
public RoundSettings<TPlayer> RoundSettings;
public string TerminationReason;
public bool ReconnectFlag;
public Squad<TPlayer>.Internal[] TeamASquadInternals;
public Squad<TPlayer>.Internal[] TeamBSquadInternals;
public Squad<TPlayer>[] TeamASquads;
public Squad<TPlayer>[] TeamBSquads;
public ItemPooling<Player<TPlayer>> PlayerPool;
// ---- Private Variables ----
public byte[] mKeepAliveBuffer;
@ -776,7 +951,7 @@ namespace BattleBitAPI.Server
public StringBuilder mBuilder;
public Queue<(ulong steamID, PlayerModifications<TPlayer>.mPlayerModifications)> mChangedModifications;
public Internal()
public Internal(GameServer<TPlayer> server)
{
this.TerminationReason = string.Empty;
this.mWriteStream = new Common.Serialization.Stream()
@ -806,6 +981,281 @@ namespace BattleBitAPI.Server
this.GamemodeRotation = new GamemodeRotation<TPlayer>(this);
this.RoundSettings = new RoundSettings<TPlayer>(this);
this.mChangedModifications = new Queue<(ulong steamID, PlayerModifications<TPlayer>.mPlayerModifications)>(254);
this.TeamASquadInternals = new Squad<TPlayer>.Internal[]
{
null,
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Alpha),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Bravo),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Charlie),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Delta ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Echo ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Foxtrot ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Golf ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Hotel ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.India),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Juliett ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Kilo ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Lima ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Mike ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.November),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Oscar ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Papa ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Quebec),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Romeo ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Sierra),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Tango ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Uniform ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Whiskey ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Xray ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Yankee ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Zulu ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Ash ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Baker ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Cast ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Diver),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Eagle),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Fisher),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.George),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Hanover),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Ice ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Jake),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.King),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Lash),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Mule),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Neptune ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Ostend),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Page ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Quail ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Raft ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Scout ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Tare ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Unit ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.William ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Xaintrie ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Yoke ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Zebra ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Ace ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Beer ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Cast2 ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Duff ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Edward ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Freddy),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Gustav),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Henry ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Ivar ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Jazz ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Key ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Lincoln ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Mary ),
new Squad<TPlayer>.Internal(server,Team.TeamA, Squads.Nora ),
};
this.TeamBSquadInternals = new Squad<TPlayer>.Internal[]
{
null,
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Alpha),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Bravo),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Charlie),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Delta ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Echo ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Foxtrot ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Golf ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Hotel ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.India),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Juliett ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Kilo ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Lima ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Mike ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.November),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Oscar ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Papa ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Quebec),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Romeo ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Sierra),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Tango ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Uniform ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Whiskey ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Xray ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Yankee ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Zulu ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Ash ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Baker ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Cast ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Diver),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Eagle),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Fisher),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.George),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Hanover),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Ice ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Jake),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.King),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Lash),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Mule),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Neptune ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Ostend),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Page ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Quail ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Raft ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Scout ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Tare ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Unit ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.William ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Xaintrie ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Yoke ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Zebra ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Ace ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Beer ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Cast2 ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Duff ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Edward ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Freddy),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Gustav),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Henry ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Ivar ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Jazz ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Key ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Lincoln ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Mary ),
new Squad<TPlayer>.Internal(server,Team.TeamB, Squads.Nora ),
};
this.TeamASquads = new Squad<TPlayer>[]
{
null,
new Squad<TPlayer>(this.TeamASquadInternals[01]),
new Squad<TPlayer>(this.TeamASquadInternals[02]),
new Squad<TPlayer>(this.TeamASquadInternals[03]),
new Squad<TPlayer>(this.TeamASquadInternals[04]),
new Squad<TPlayer>(this.TeamASquadInternals[05]),
new Squad<TPlayer>(this.TeamASquadInternals[06]),
new Squad<TPlayer>(this.TeamASquadInternals[07]),
new Squad<TPlayer>(this.TeamASquadInternals[08]),
new Squad<TPlayer>(this.TeamASquadInternals[09]),
new Squad<TPlayer>(this.TeamASquadInternals[10]),
new Squad<TPlayer>(this.TeamASquadInternals[11]),
new Squad<TPlayer>(this.TeamASquadInternals[12]),
new Squad<TPlayer>(this.TeamASquadInternals[13]),
new Squad<TPlayer>(this.TeamASquadInternals[14]),
new Squad<TPlayer>(this.TeamASquadInternals[15]),
new Squad<TPlayer>(this.TeamASquadInternals[16]),
new Squad<TPlayer>(this.TeamASquadInternals[17]),
new Squad<TPlayer>(this.TeamASquadInternals[18]),
new Squad<TPlayer>(this.TeamASquadInternals[19]),
new Squad<TPlayer>(this.TeamASquadInternals[20]),
new Squad<TPlayer>(this.TeamASquadInternals[21]),
new Squad<TPlayer>(this.TeamASquadInternals[22]),
new Squad<TPlayer>(this.TeamASquadInternals[23]),
new Squad<TPlayer>(this.TeamASquadInternals[24]),
new Squad<TPlayer>(this.TeamASquadInternals[25]),
new Squad<TPlayer>(this.TeamASquadInternals[26]),
new Squad<TPlayer>(this.TeamASquadInternals[27]),
new Squad<TPlayer>(this.TeamASquadInternals[28]),
new Squad<TPlayer>(this.TeamASquadInternals[29]),
new Squad<TPlayer>(this.TeamASquadInternals[30]),
new Squad<TPlayer>(this.TeamASquadInternals[31]),
new Squad<TPlayer>(this.TeamASquadInternals[32]),
new Squad<TPlayer>(this.TeamASquadInternals[33]),
new Squad<TPlayer>(this.TeamASquadInternals[34]),
new Squad<TPlayer>(this.TeamASquadInternals[35]),
new Squad<TPlayer>(this.TeamASquadInternals[36]),
new Squad<TPlayer>(this.TeamASquadInternals[37]),
new Squad<TPlayer>(this.TeamASquadInternals[38]),
new Squad<TPlayer>(this.TeamASquadInternals[39]),
new Squad<TPlayer>(this.TeamASquadInternals[40]),
new Squad<TPlayer>(this.TeamASquadInternals[41]),
new Squad<TPlayer>(this.TeamASquadInternals[42]),
new Squad<TPlayer>(this.TeamASquadInternals[43]),
new Squad<TPlayer>(this.TeamASquadInternals[44]),
new Squad<TPlayer>(this.TeamASquadInternals[45]),
new Squad<TPlayer>(this.TeamASquadInternals[46]),
new Squad<TPlayer>(this.TeamASquadInternals[47]),
new Squad<TPlayer>(this.TeamASquadInternals[48]),
new Squad<TPlayer>(this.TeamASquadInternals[49]),
new Squad<TPlayer>(this.TeamASquadInternals[50]),
new Squad<TPlayer>(this.TeamASquadInternals[51]),
new Squad<TPlayer>(this.TeamASquadInternals[52]),
new Squad<TPlayer>(this.TeamASquadInternals[53]),
new Squad<TPlayer>(this.TeamASquadInternals[54]),
new Squad<TPlayer>(this.TeamASquadInternals[55]),
new Squad<TPlayer>(this.TeamASquadInternals[56]),
new Squad<TPlayer>(this.TeamASquadInternals[57]),
new Squad<TPlayer>(this.TeamASquadInternals[58]),
new Squad<TPlayer>(this.TeamASquadInternals[59]),
new Squad<TPlayer>(this.TeamASquadInternals[60]),
new Squad<TPlayer>(this.TeamASquadInternals[61]),
new Squad<TPlayer>(this.TeamASquadInternals[62]),
new Squad<TPlayer>(this.TeamASquadInternals[63]),
new Squad<TPlayer>(this.TeamASquadInternals[64]),
};
this.TeamBSquads = new Squad<TPlayer>[]
{
null,
new Squad<TPlayer>(this.TeamBSquadInternals[01]),
new Squad<TPlayer>(this.TeamBSquadInternals[02]),
new Squad<TPlayer>(this.TeamBSquadInternals[03]),
new Squad<TPlayer>(this.TeamBSquadInternals[04]),
new Squad<TPlayer>(this.TeamBSquadInternals[05]),
new Squad<TPlayer>(this.TeamBSquadInternals[06]),
new Squad<TPlayer>(this.TeamBSquadInternals[07]),
new Squad<TPlayer>(this.TeamBSquadInternals[08]),
new Squad<TPlayer>(this.TeamBSquadInternals[09]),
new Squad<TPlayer>(this.TeamBSquadInternals[10]),
new Squad<TPlayer>(this.TeamBSquadInternals[11]),
new Squad<TPlayer>(this.TeamBSquadInternals[12]),
new Squad<TPlayer>(this.TeamBSquadInternals[13]),
new Squad<TPlayer>(this.TeamBSquadInternals[14]),
new Squad<TPlayer>(this.TeamBSquadInternals[15]),
new Squad<TPlayer>(this.TeamBSquadInternals[16]),
new Squad<TPlayer>(this.TeamBSquadInternals[17]),
new Squad<TPlayer>(this.TeamBSquadInternals[18]),
new Squad<TPlayer>(this.TeamBSquadInternals[19]),
new Squad<TPlayer>(this.TeamBSquadInternals[20]),
new Squad<TPlayer>(this.TeamBSquadInternals[21]),
new Squad<TPlayer>(this.TeamBSquadInternals[22]),
new Squad<TPlayer>(this.TeamBSquadInternals[23]),
new Squad<TPlayer>(this.TeamBSquadInternals[24]),
new Squad<TPlayer>(this.TeamBSquadInternals[25]),
new Squad<TPlayer>(this.TeamBSquadInternals[26]),
new Squad<TPlayer>(this.TeamBSquadInternals[27]),
new Squad<TPlayer>(this.TeamBSquadInternals[28]),
new Squad<TPlayer>(this.TeamBSquadInternals[29]),
new Squad<TPlayer>(this.TeamBSquadInternals[30]),
new Squad<TPlayer>(this.TeamBSquadInternals[31]),
new Squad<TPlayer>(this.TeamBSquadInternals[32]),
new Squad<TPlayer>(this.TeamBSquadInternals[33]),
new Squad<TPlayer>(this.TeamBSquadInternals[34]),
new Squad<TPlayer>(this.TeamBSquadInternals[35]),
new Squad<TPlayer>(this.TeamBSquadInternals[36]),
new Squad<TPlayer>(this.TeamBSquadInternals[37]),
new Squad<TPlayer>(this.TeamBSquadInternals[38]),
new Squad<TPlayer>(this.TeamBSquadInternals[39]),
new Squad<TPlayer>(this.TeamBSquadInternals[40]),
new Squad<TPlayer>(this.TeamBSquadInternals[41]),
new Squad<TPlayer>(this.TeamBSquadInternals[42]),
new Squad<TPlayer>(this.TeamBSquadInternals[43]),
new Squad<TPlayer>(this.TeamBSquadInternals[44]),
new Squad<TPlayer>(this.TeamBSquadInternals[45]),
new Squad<TPlayer>(this.TeamBSquadInternals[46]),
new Squad<TPlayer>(this.TeamBSquadInternals[47]),
new Squad<TPlayer>(this.TeamBSquadInternals[48]),
new Squad<TPlayer>(this.TeamBSquadInternals[49]),
new Squad<TPlayer>(this.TeamBSquadInternals[50]),
new Squad<TPlayer>(this.TeamBSquadInternals[51]),
new Squad<TPlayer>(this.TeamBSquadInternals[52]),
new Squad<TPlayer>(this.TeamBSquadInternals[53]),
new Squad<TPlayer>(this.TeamBSquadInternals[54]),
new Squad<TPlayer>(this.TeamBSquadInternals[55]),
new Squad<TPlayer>(this.TeamBSquadInternals[56]),
new Squad<TPlayer>(this.TeamBSquadInternals[57]),
new Squad<TPlayer>(this.TeamBSquadInternals[58]),
new Squad<TPlayer>(this.TeamBSquadInternals[59]),
new Squad<TPlayer>(this.TeamBSquadInternals[60]),
new Squad<TPlayer>(this.TeamBSquadInternals[61]),
new Squad<TPlayer>(this.TeamBSquadInternals[62]),
new Squad<TPlayer>(this.TeamBSquadInternals[63]),
new Squad<TPlayer>(this.TeamBSquadInternals[64]),
};
this.PlayerPool = new ItemPooling<Player<TPlayer>>(254);
}
// ---- Players In Room ----
@ -894,6 +1344,7 @@ namespace BattleBitAPI.Server
this.mBuilder.Clear();
this.mChangedModifications.Clear();
}
public void AddPlayer(Player<TPlayer> player)
{
lock (Players)
@ -912,6 +1363,18 @@ namespace BattleBitAPI.Server
lock (Players)
return Players.TryGetValue(steamID, out result);
}
public Squad<TPlayer>.Internal GetSquadInternal(Team team, Squads squad)
{
if (team == Team.TeamA)
return this.TeamASquadInternals[(int)squad];
if (team == Team.TeamB)
return this.TeamBSquadInternals[(int)squad];
return null;
}
public Squad<TPlayer>.Internal GetSquadInternal(Squad<TPlayer> squad)
{
return GetSquadInternal(squad.Team, squad.Name);
}
}
}
}

View File

@ -0,0 +1,58 @@
using BattleBitAPI.Common;
namespace BattleBitAPI.Server
{
public class Squad<TPlayer> where TPlayer : Player<TPlayer>
{
public Team Team => @internal.Team;
public Squads Name => @internal.Name;
public GameServer<TPlayer> Server => @internal.Server;
public int NumberOfMembers => @internal.Members.Count;
public bool IsEmpty => NumberOfMembers == 0;
public IEnumerable<TPlayer> Members => @internal.Server.IterateMembersOf(this);
public int SquadPoints
{
get => @internal.SquadPoints;
set
{
@internal.SquadPoints = value;
Server.SetSquadPointsOf(@internal.Team, @internal.Name, value);
}
}
private Internal @internal;
public Squad(Internal @internal)
{
this.@internal = @internal;
}
public override string ToString()
{
return Team + " : " + Name;
}
// ---- Internal ----
public class Internal
{
public readonly Team Team;
public readonly Squads Name;
public int SquadPoints;
public GameServer<TPlayer> Server;
public HashSet<TPlayer> Members;
public Internal(GameServer<TPlayer> server, Team team, Squads squads)
{
this.Team = team;
this.Name = squads;
this.Server = server;
this.Members = new HashSet<TPlayer>(8);
}
public void Reset()
{
}
}
}
}

View File

@ -33,12 +33,12 @@ namespace BattleBitAPI
ChangeTeam(value);
}
}
public Squads Squad
public Squads SquadName
{
get => mInternal.Squad;
get => mInternal.SquadName;
set
{
if (value == mInternal.Squad)
if (value == mInternal.SquadName)
return;
if (value == Squads.NoSquad)
KickFromSquad();
@ -46,7 +46,25 @@ namespace BattleBitAPI
JoinSquad(value);
}
}
public bool InSquad => mInternal.Squad != Squads.NoSquad;
public Squad<TPlayer> Squad
{
get => GameServer.GetSquad(mInternal.Team, mInternal.SquadName);
set
{
if (value == Squad)
return;
if (value == null)
KickFromSquad();
else
{
if(value.Team != this.Team)
ChangeTeam(value.Team);
JoinSquad(value.Name);
}
}
}
public bool InSquad => mInternal.SquadName != Squads.NoSquad;
public int PingMs => mInternal.PingMs;
public float HP
@ -127,11 +145,11 @@ namespace BattleBitAPI
{
}
public virtual async Task OnJoinedSquad(Squads newSquad)
public virtual async Task OnJoinedSquad(Squad<TPlayer> newSquad)
{
}
public virtual async Task OnLeftSquad(Squads oldSquad)
public virtual async Task OnLeftSquad(Squad<TPlayer> oldSquad)
{
}
@ -255,7 +273,7 @@ namespace BattleBitAPI
public GameServer<TPlayer> GameServer;
public GameRole Role;
public Team Team;
public Squads Squad;
public Squads SquadName;
public int PingMs = 999;
public bool IsAlive;

View File

@ -79,9 +79,10 @@ namespace BattleBitAPI.Server
/// </summary>
///
/// <remarks>
/// GameServer: Game server that has been just created.<br/>
/// IPAddress: Game server's IP.<br/>
/// ushort: Game server's Port.<br/>
/// </remarks>
public Func<TGameServer> OnCreatingGameServerInstance { get; set; }
public Func<IPAddress, ushort, TGameServer> OnCreatingGameServerInstance { get; set; }
/// <summary>
/// Fired when a new instance of player instance created.
@ -89,8 +90,9 @@ namespace BattleBitAPI.Server
///
/// <remarks>
/// TPlayer: The player instance that was created<br/>
/// ulong: The steamID of the player<br/>
/// </remarks>
public Func<TPlayer> OnCreatingPlayerInstance { get; set; }
public Func<ulong, TPlayer> OnCreatingPlayerInstance { get; set; }
// --- Private ---
private TcpListener mSocket;
@ -190,7 +192,7 @@ namespace BattleBitAPI.Server
throw new Exception("Incoming package wasn't hail.");
}
//Read the server name
//Read the server token
string token;
{
readStream.Reset();
@ -208,6 +210,27 @@ namespace BattleBitAPI.Server
token = readStream.ReadString(stringSize);
}
//Read the server version
string version;
{
readStream.Reset();
if (!await networkStream.TryRead(readStream, 2, source.Token))
throw new Exception("Unable to read the version size");
int stringSize = readStream.ReadUInt16();
if (stringSize > 32)
throw new Exception("Invalid version size");
readStream.Reset();
if (!await networkStream.TryRead(readStream, stringSize, source.Token))
throw new Exception("Unable to read the version");
version = readStream.ReadString(stringSize);
}
if (version != Const.Version)
throw new Exception("Incoming server's version `" + version + "` does not match with current API version `" + Const.Version + "`");
//Read port
int gamePort;
{
@ -382,7 +405,7 @@ namespace BattleBitAPI.Server
}
var hash = ((ulong)gamePort << 32) | (ulong)ip.ToUInt();
server = this.mInstanceDatabase.GetServerInstance(hash, out resources, this.OnCreatingGameServerInstance);
server = this.mInstanceDatabase.GetServerInstance(hash, out resources, this.OnCreatingGameServerInstance, ip, (ushort)gamePort);
resources.Set(
this.mExecutePackage,
this.mGetPlayerInternals,
@ -563,7 +586,7 @@ namespace BattleBitAPI.Server
playerInternal.IP = new IPAddress(ipHash);
playerInternal.GameServer = (GameServer<TPlayer>)server;
playerInternal.Team = team;
playerInternal.Squad = squad;
playerInternal.SquadName = squad;
playerInternal.Role = role;
playerInternal.IsAlive = isAlive;
playerInternal.CurrentLoadout = loadout;
@ -585,6 +608,42 @@ namespace BattleBitAPI.Server
resources.AddPlayer(player);
}
//Squads
{
readStream.Reset();
if (!await networkStream.TryRead(readStream, 4, source.Token))
throw new Exception("Unable to read the Squad size");
int squadsDataSize = (int)readStream.ReadUInt32();
readStream.Reset();
if (!await networkStream.TryRead(readStream, squadsDataSize, source.Token))
throw new Exception("Unable to read the Squads");
for (int i = 1; i < resources.TeamASquadInternals.Length; i++)
{
var item = resources.TeamASquadInternals[i];
item.SquadPoints = readStream.ReadInt32();
}
for (int i = 1; i < resources.TeamBSquadInternals.Length; i++)
{
var item = resources.TeamBSquadInternals[i];
item.SquadPoints = readStream.ReadInt32();
}
}
// --- Finished Reading ---
//Assing each player to their squad.
foreach (var item in resources.Players.Values)
{
if (item.InSquad)
{
var @squad = resources.GetSquadInternal(item.Squad);
lock (@squad.Members)
@squad.Members.Add((TPlayer)item);
}
}
//Send accepted notification.
networkStream.WriteByte((byte)NetworkCommuncation.Accepted);
}
@ -711,7 +770,7 @@ namespace BattleBitAPI.Server
playerInternal.GameServer = (GameServer<TPlayer>)server;
playerInternal.Team = team;
playerInternal.Squad = squad;
playerInternal.SquadName = squad;
playerInternal.Role = role;
//Start from default.
@ -745,6 +804,19 @@ namespace BattleBitAPI.Server
server.OnPlayerDied((TPlayer)player);
}
if (@internal.SquadName != Squads.NoSquad)
{
var msquad = server.GetSquad(@internal.Team, @internal.SquadName);
var rsquad = resources.GetSquadInternal(msquad);
@internal.SquadName = Squads.NoSquad;
lock (rsquad.Members)
rsquad.Members.Remove((TPlayer)player);
player.OnLeftSquad(msquad);
server.OnPlayerLeftSquad((TPlayer)player, msquad);
}
player.OnDisconnected();
server.OnPlayerDisconnected((TPlayer)player);
}
@ -916,10 +988,15 @@ namespace BattleBitAPI.Server
if (resources.TryGetPlayer(steamID, out var client))
{
var @internal = mInstanceDatabase.GetPlayerInternals(steamID);
@internal.Squad = squad;
@internal.SquadName = squad;
client.OnJoinedSquad(squad);
server.OnPlayerJoinedSquad((TPlayer)client, squad);
var msquad = server.GetSquad(client.Team, squad);
var rsquad = resources.GetSquadInternal(msquad);
lock (rsquad.Members)
rsquad.Members.Add((TPlayer)client);
client.OnJoinedSquad(msquad);
server.OnPlayerJoinedSquad((TPlayer)client, msquad);
}
}
break;
@ -934,13 +1011,20 @@ namespace BattleBitAPI.Server
{
var @internal = mInstanceDatabase.GetPlayerInternals(steamID);
var oldSquad = client.Squad;
var oldSquad = client.SquadName;
var oldRole = client.Role;
@internal.Squad = Squads.NoSquad;
@internal.SquadName = Squads.NoSquad;
@internal.Role = GameRole.Assault;
client.OnLeftSquad(oldSquad);
server.OnPlayerLeftSquad((TPlayer)client, oldSquad);
var msquad = server.GetSquad(client.Team, oldSquad);
var rsquad = resources.GetSquadInternal(msquad);
@internal.SquadName = Squads.NoSquad;
lock (rsquad.Members)
rsquad.Members.Remove((TPlayer)client);
client.OnLeftSquad(msquad);
server.OnPlayerLeftSquad((TPlayer)client, msquad);
if (oldRole != GameRole.Assault)
{
@ -976,7 +1060,7 @@ namespace BattleBitAPI.Server
{
ulong steamID = stream.ReadUInt64();
var request = new OnPlayerSpawnArguments();
OnPlayerSpawnArguments request = new OnPlayerSpawnArguments();
request.Read(stream);
ushort vehicleID = stream.ReadUInt16();
@ -984,15 +1068,25 @@ namespace BattleBitAPI.Server
{
async Task mHandle()
{
request = await server.OnPlayerSpawning((TPlayer)client, request);
var responseSpawn = await server.OnPlayerSpawning((TPlayer)client, request);
//Respond back.
using (var response = Common.Serialization.Stream.Get())
{
response.Write((byte)NetworkCommuncation.SpawnPlayer);
response.Write(steamID);
request.Write(response);
response.Write(vehicleID);
if (responseSpawn != null)
{
response.Write(true);
request.Write(response);
response.Write(vehicleID);
}
else
{
response.Write(false);
}
server.WriteToSocket(response);
}
}
@ -1218,6 +1312,25 @@ namespace BattleBitAPI.Server
}
break;
}
case NetworkCommuncation.OnSquadPointsChanged:
{
if (stream.CanRead(1 + 1 + 4))
{
Team team = (Team)stream.ReadInt8();
Squads squad = (Squads)stream.ReadInt8();
int points = stream.ReadInt32();
var msquad = server.GetSquad(team, squad);
var rsquad = resources.GetSquadInternal(msquad);
if (rsquad.SquadPoints != points)
{
rsquad.SquadPoints = points;
server.OnSquadPointsChanged(msquad, points);
}
}
break;
}
}
}
@ -1281,7 +1394,7 @@ namespace BattleBitAPI.Server
this.mPlayerInstances = new Dictionary<ulong, (TPlayer, Player<TPlayer>.Internal)>(1024 * 16);
}
public TGameServer GetServerInstance(ulong hash, out GameServer<TPlayer>.Internal @internal, Func<TGameServer> createFunc)
public TGameServer GetServerInstance(ulong hash, out GameServer<TPlayer>.Internal @internal, Func<IPAddress, ushort, TGameServer> createFunc, IPAddress ip, ushort port)
{
lock (mGameServerInstances)
{
@ -1291,13 +1404,13 @@ namespace BattleBitAPI.Server
return data.Item1;
}
@internal = new GameServer<TPlayer>.Internal();
GameServer<TPlayer> server;
if (createFunc != null)
server = createFunc();
server = createFunc(ip, port);
else
server = Activator.CreateInstance<GameServer<TPlayer>>();
server = Activator.CreateInstance<TGameServer>();
@internal = new GameServer<TPlayer>.Internal(server);
GameServer<TPlayer>.SetInstance(server, @internal);
@ -1305,7 +1418,7 @@ namespace BattleBitAPI.Server
return (TGameServer)server;
}
}
public TPlayer GetPlayerInstance(ulong steamID, out Player<TPlayer>.Internal @internal, Func<TPlayer> createFunc)
public TPlayer GetPlayerInstance(ulong steamID, out Player<TPlayer>.Internal @internal, Func<ulong, TPlayer> createFunc)
{
lock (this.mPlayerInstances)
{
@ -1320,7 +1433,7 @@ namespace BattleBitAPI.Server
Player<TPlayer> pplayer;
if (createFunc != null)
pplayer = createFunc();
pplayer = createFunc(steamID);
else
pplayer = Activator.CreateInstance<TPlayer>();
Player<TPlayer>.SetInstance((TPlayer)pplayer, @internal);

View File

@ -1,11 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<OutputType>Library</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Title>BattleBitRemastered.CommunityAPI.Core</Title>
<Authors>SgtOkiDoki</Authors>
<Company>OkigamesLimited</Company>
<Product>BattleBit Remastered</Product>
<Description>API to customize game servers for BattleBit Remastered.
</Description>
<Copyright>MIT</Copyright>
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageProjectUrl>https://github.com/MrOkiDoki/BattleBit-Community-Server-API</PackageProjectUrl>
<RepositoryUrl>https://github.com/MrOkiDoki/BattleBit-Community-Server-API</RepositoryUrl>
<PackageTags>BattleBit</PackageTags>
</PropertyGroup>
<ItemGroup>
<None Update="README.md">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
</Project>

View File

@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33205.214
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommunityServerAPI", "CommunityServerAPI.csproj", "{787887A1-8AEE-43E4-AF9B-A3883DE04486}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommunityServerAPI", "CommunityServerAPI.csproj", "{787887A1-8AEE-43E4-AF9B-A3883DE04486}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BattleBitAPI.Program", "..\BattleBitAPI.Program\BattleBitAPI.Program.csproj", "{96D55E1B-2711-47E2-9DA1-41B645F4FCF2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -15,6 +17,10 @@ Global
{787887A1-8AEE-43E4-AF9B-A3883DE04486}.Debug|Any CPU.Build.0 = Debug|Any CPU
{787887A1-8AEE-43E4-AF9B-A3883DE04486}.Release|Any CPU.ActiveCfg = Release|Any CPU
{787887A1-8AEE-43E4-AF9B-A3883DE04486}.Release|Any CPU.Build.0 = Release|Any CPU
{96D55E1B-2711-47E2-9DA1-41B645F4FCF2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{96D55E1B-2711-47E2-9DA1-41B645F4FCF2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{96D55E1B-2711-47E2-9DA1-41B645F4FCF2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{96D55E1B-2711-47E2-9DA1-41B645F4FCF2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -1,106 +0,0 @@
using BattleBitAPI;
using BattleBitAPI.Common;
using BattleBitAPI.Server;
using System.Linq.Expressions;
using System.Net;
using System.Numerics;
using System.Threading.Channels;
using System.Xml;
class Program
{
static void Main(string[] args)
{
var listener = new ServerListener<MyPlayer, MyGameServer>();
listener.OnCreatingGameServerInstance += OnCreatingGameServerInstance;
listener.OnCreatingPlayerInstance += OnCreatingPlayerInstance;
listener.Start(29294);
Thread.Sleep(-1);
}
private static MyPlayer OnCreatingPlayerInstance()
{
return new MyPlayer("asdasd");
}
private static MyGameServer OnCreatingGameServerInstance()
{
return new MyGameServer("mysecretDBpass");
}
}
class MyPlayer : Player<MyPlayer>
{
private string mydb;
public MyPlayer(string mydb)
{
this.mydb = mydb;
}
public override async Task OnSpawned()
{
}
}
class MyGameServer : GameServer<MyPlayer>
{
private string myDbConnection;
public MyGameServer(string mySecretDBConnection)
{
this.myDbConnection = mySecretDBConnection;
}
public override async Task OnConnected()
{
ForceStartGame();
ServerSettings.PlayerCollision = true;
}
public override async Task OnTick()
{
}
public override async Task<OnPlayerSpawnArguments> OnPlayerSpawning(MyPlayer player, OnPlayerSpawnArguments request)
{
request.Wearings.Eye = "Eye_Zombie_01";
request.Wearings.Face = "Face_Zombie_01";
request.Wearings.Face = "Hair_Zombie_01";
request.Wearings.Skin = "Zombie_01";
request.Wearings.Uniform = "ANY_NU_Uniform_Zombie_01";
request.Wearings.Head = "ANV2_Universal_Zombie_Helmet_00_A_Z";
request.Wearings.Belt = "ANV2_Universal_All_Belt_Null";
request.Wearings.Backbag = "ANV2_Universal_All_Backpack_Null";
request.Wearings.Chest = "ANV2_Universal_All_Armor_Null";
return request;
}
public override async Task OnPlayerConnected(MyPlayer player)
{
await Console.Out.WriteLineAsync("Connected: " + player);
player.Modifications.CanSpectate = true;
player.Modifications.CanDeploy = false;
}
public override async Task OnPlayerSpawned(MyPlayer player)
{
await Console.Out.WriteLineAsync("Spawned: " + player);
}
public override async Task OnAPlayerDownedAnotherPlayer(OnPlayerKillArguments<MyPlayer> args)
{
await Console.Out.WriteLineAsync("Downed: " + args.Victim);
}
public override async Task OnPlayerGivenUp(MyPlayer player)
{
await Console.Out.WriteLineAsync("Giveup: " + player);
}
public override async Task OnPlayerDied(MyPlayer player)
{
await Console.Out.WriteLineAsync("Died: " + player);
}
public override async Task OnAPlayerRevivedAnotherPlayer(MyPlayer from, MyPlayer to)
{
await Console.Out.WriteLineAsync(from + " revived " + to);
}
public override async Task OnPlayerDisconnected(MyPlayer player)
{
await Console.Out.WriteLineAsync("Disconnected: " + player);
}
}