mirror of
https://github.com/SoDOff-Project/sodoff-mmo.git
synced 2025-10-11 08:18:49 -07:00
support for "WorldEvents" (ship battle)
This commit is contained in:
parent
045a413998
commit
7cc20ae3bb
@ -9,7 +9,7 @@ class DateTimeHandler : ICommandHandler {
|
||||
public void Handle(Client client, NetworkObject receivedObject) {
|
||||
NetworkObject cmd = new();
|
||||
NetworkObject obj = new();
|
||||
obj.Add("arr", new string[] { "DT", DateTime.UtcNow.ToString("MM/dd/yyyy HH:mm") });
|
||||
obj.Add("arr", new string[] { "DT", DateTime.UtcNow.ToString("MM/dd/yyyy HH:mm:ss") });
|
||||
cmd.Add("c", "DT");
|
||||
cmd.Add("p", obj);
|
||||
client.Send(NetworkObject.WrapObject(1, 13, cmd).Serialize());
|
||||
|
@ -14,9 +14,7 @@ class JoinRoomHandler : ICommandHandler
|
||||
string roomName = receivedObject.Get<NetworkObject>("p").Get<string>("rn");
|
||||
client.LeaveRoom();
|
||||
client.InvalidatePlayerData();
|
||||
if (!Room.Exists(roomName))
|
||||
Room.Add(roomName);
|
||||
room = Room.Get(roomName);
|
||||
room = Room.GetOrAdd(roomName);
|
||||
Console.WriteLine($"Join Room: {roomName} RoomID: {room.Id} IID: {client.ClientID}");
|
||||
this.client = client;
|
||||
|
||||
|
@ -28,6 +28,25 @@ class LoginHandler : ICommandHandler
|
||||
|
||||
NetworkArray r2 = new();
|
||||
|
||||
NetworkArray we = new();
|
||||
NetworkArray we1 = new();
|
||||
NetworkArray we2 = new();
|
||||
|
||||
we1.Add("WE_ScoutAttack");
|
||||
we1.Add((Byte)4);
|
||||
we1.Add(WorldEvent.Get().EventInfo());
|
||||
we1.Add(false);
|
||||
we1.Add(true);
|
||||
|
||||
we2.Add("WEN_ScoutAttack");
|
||||
we2.Add((Byte)4);
|
||||
we2.Add(WorldEvent.Get().EventInfoNext());
|
||||
we2.Add(false);
|
||||
we2.Add(true);
|
||||
|
||||
we.Add(we1);
|
||||
we.Add(we2);
|
||||
|
||||
r2.Add(1);
|
||||
r2.Add("ADMIN");
|
||||
r2.Add("default");
|
||||
@ -36,7 +55,7 @@ class LoginHandler : ICommandHandler
|
||||
r2.Add(true);
|
||||
r2.Add((short)0);
|
||||
r2.Add((short)1);
|
||||
r2.Add(new NetworkArray());
|
||||
r2.Add(we);
|
||||
rl.Add(r2);
|
||||
|
||||
NetworkArray r3 = new();
|
||||
|
115
src/CommandHandlers/WorldEventHandlers.cs
Normal file
115
src/CommandHandlers/WorldEventHandlers.cs
Normal file
@ -0,0 +1,115 @@
|
||||
using System.Globalization;
|
||||
using sodoffmmo.Attributes;
|
||||
using sodoffmmo.Core;
|
||||
using sodoffmmo.Data;
|
||||
|
||||
namespace sodoffmmo.CommandHandlers;
|
||||
|
||||
[ExtensionCommandHandler("wex.WES")] // event status request
|
||||
class WorldEventStatusHandler : ICommandHandler {
|
||||
public void Handle(Client client, NetworkObject receivedObject) {
|
||||
client.Send(Utils.ArrNetworkPacket( new string[] {
|
||||
"WESR",
|
||||
"WE_ScoutAttack|" + WorldEvent.Get().EventInfo()
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
[ExtensionCommandHandler("wex.OV")]
|
||||
class WorldEventHealthHandler : ICommandHandler {
|
||||
// rec: {"a":13,"c":1,"p":{"c":"wex.OV","p":{"en":"","event":"ScoutAttack","eventUID":"ZydLUmCC","oh":"0.003444444","uid":"ZydLUmCC1"},"r":-1}}
|
||||
public void Handle(Client client, NetworkObject receivedObject) {
|
||||
NetworkObject p = receivedObject.Get<NetworkObject>("p");
|
||||
float healthUpdateVal = float.Parse(
|
||||
p.Get<string>("oh"),
|
||||
System.Globalization.CultureInfo.InvariantCulture
|
||||
);
|
||||
string targetUid = p.Get<string>("uid");
|
||||
|
||||
float health = WorldEvent.Get().UpdateHealth(targetUid, healthUpdateVal);
|
||||
|
||||
if (health >= 0.0f) {
|
||||
// send: {"a":11,"c":0,"p":{"r":367256,"vl":[["WEH_ZydLUmCC1",4,"0.33133352,Thu Jun 22 02:02:43 UTC 2023",false,false]]}}
|
||||
NetworkPacket packet = Utils.VlNetworkPacket(
|
||||
"WEH_" + targetUid,
|
||||
health.ToString("0.0#####", CultureInfo.GetCultureInfo("en-US")) + "," + DateTime.UtcNow.ToString("ddd MMM dd HH:mm:ss UTC yyyy", CultureInfo.GetCultureInfo("en-US"))
|
||||
);
|
||||
foreach (var roomClient in WorldEvent.Get().GetRoom().Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ExtensionCommandHandler("wex.OVF")] // flare info from ship AI -> resend as WEF_
|
||||
class WorldEventFlareHandler : ICommandHandler {
|
||||
// rec: {"a":13,"c":1,"p":{"c":"wex.OVF","p":{"en":"","fuid":"WpnpDyJ51,14,0","oh":"0","ts":"6/29/2023 3:03:18 AM"},"r":-1}}
|
||||
public void Handle(Client client, NetworkObject receivedObject) {
|
||||
NetworkObject p = receivedObject.Get<NetworkObject>("p");
|
||||
|
||||
// send: {"a":11,"c":0,"p":{"r":403777,"vl":[["WEF_WpnpDyJ51,14,0",4,"0,6/29/2023 3:03:18 AM",false,false]]}}
|
||||
NetworkPacket packet = Utils.VlNetworkPacket(
|
||||
"WEF_" + p.Get<string>("fuid"),
|
||||
p.Get<string>("oh") + "," + p.Get<string>("ts")
|
||||
);
|
||||
foreach (var roomClient in WorldEvent.Get().GetRoom().Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ExtensionCommandHandler("wex.ST")] // missile info from ship AI -> resend as WA
|
||||
class WorldEventMissileHandler : ICommandHandler {
|
||||
// rec: {"a":13,"c":1,"p":{"c":"wex.ST","p":{"en":"","objID":"-4X_gWAo1","tID":"f5b6254a-df78-4e24-aa9d-7e14539fb858","uID":"1f8eeb6b-753f-4e7f-af13-42cdd69d14e7","wID":"5"},"r":-1}}
|
||||
public void Handle(Client client, NetworkObject receivedObject) {
|
||||
NetworkObject p = receivedObject.Get<NetworkObject>("p");
|
||||
|
||||
// send: {"a":13,"c":1,"p":{"c":"","p":{"arr":["WA","1f8eeb6b-753f-4e7f-af13-42cdd69d14e7","5","f5b6254a-df78-4e24-aa9d-7e14539fb858","-4X_gWAo1"]}}}
|
||||
NetworkPacket packet = Utils.ArrNetworkPacket(new string[] {
|
||||
"WA",
|
||||
p.Get<string>("uID"),
|
||||
p.Get<string>("wID"),
|
||||
p.Get<string>("tID"),
|
||||
p.Get<string>("objID")
|
||||
});
|
||||
foreach (var roomClient in WorldEvent.Get().GetRoom().Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[ExtensionCommandHandler("wex.PS")]
|
||||
class WorldEventScoreHandler : ICommandHandler {
|
||||
// rec: {"a":13,"c":1,"p":{"c":"wex.PS","p":{"ScoreData":"Datashyo/10","en":"","id":"ScoutAttack"},"r":-1}}
|
||||
public void Handle(Client client, NetworkObject receivedObject) {
|
||||
string scoreData = receivedObject.Get<NetworkObject>("p").Get<string>("ScoreData");
|
||||
WorldEvent.Get().UpdateScore(client, scoreData);
|
||||
}
|
||||
}
|
||||
|
||||
[ExtensionCommandHandler("wex.AIACK")] // AI ack
|
||||
class WorldEventAIACKHandler : ICommandHandler {
|
||||
// rec: {"a":13,"c":1,"p":{"c":"wex.AIACK","p":{"en":"","id":"f322dd98-e9fb-4b2d-a5e0-1c98680517b5","uid":"SoDOff1"},"r":-1}}
|
||||
public void Handle(Client client, NetworkObject receivedObject) {
|
||||
WorldEvent.Get().UpdateAI(client);
|
||||
}
|
||||
}
|
||||
[ExtensionCommandHandler("wex.AIP")] // AI ping
|
||||
class WorldEventAIPingHandler : ICommandHandler {
|
||||
// rec: {"a":13,"c":1,"p":{"c":"wex.AIP","p":{"en":""},"r":-1}}
|
||||
public void Handle(Client client, NetworkObject receivedObject) {
|
||||
WorldEvent.Get().UpdateAI(client);
|
||||
}
|
||||
}
|
||||
|
||||
[ExtensionCommandHandler("wex.ETS")] // time span
|
||||
class WorldEventTimeSpanHandler : ICommandHandler {
|
||||
// rec: {"a":13,"c":1,"p":{"c":"wex.ETS","p":{"en":"","timeSpan":"300"},"r":-1}}
|
||||
public void Handle(Client client, NetworkObject receivedObject) {
|
||||
float timeSpan = float.Parse(
|
||||
receivedObject.Get<NetworkObject>("p").Get<string>("timeSpan"),
|
||||
System.Globalization.CultureInfo.InvariantCulture
|
||||
);
|
||||
WorldEvent.Get().SetTimeSpan(client, timeSpan);
|
||||
}
|
||||
}
|
@ -39,6 +39,12 @@ public class Room {
|
||||
|
||||
public static Room Get(string name) => rooms[name];
|
||||
|
||||
public static Room GetOrAdd(string name) {
|
||||
if (!Room.Exists(name))
|
||||
Room.Add(name);
|
||||
return rooms[name];
|
||||
}
|
||||
|
||||
public static bool Exists(string name) => rooms.ContainsKey(name);
|
||||
|
||||
public static void Add(string name) {
|
||||
|
@ -5,6 +5,8 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using sodoffmmo.Data;
|
||||
|
||||
namespace sodoffmmo.Core;
|
||||
internal static class Utils {
|
||||
public static bool VariablesValid(Client client) {
|
||||
@ -19,4 +21,32 @@ internal static class Utils {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static NetworkPacket VlNetworkPacket(NetworkArray vl2, int roomID) {
|
||||
NetworkObject wedata = new();
|
||||
NetworkArray vl = new();
|
||||
vl.Add(vl2);
|
||||
wedata.Add("r", roomID);
|
||||
wedata.Add("vl", vl);
|
||||
return NetworkObject.WrapObject(0, 11, wedata).Serialize();
|
||||
}
|
||||
|
||||
public static NetworkPacket VlNetworkPacket(string a, string b) {
|
||||
NetworkArray vl2 = new();
|
||||
vl2.Add(a);
|
||||
vl2.Add((Byte)4);
|
||||
vl2.Add(b);
|
||||
vl2.Add(false);
|
||||
vl2.Add(false);
|
||||
return VlNetworkPacket(vl2, WorldEvent.Get().GetRoom().Id);
|
||||
}
|
||||
|
||||
public static NetworkPacket ArrNetworkPacket(string[] data) {
|
||||
NetworkObject cmd = new();
|
||||
NetworkObject obj = new();
|
||||
obj.Add("arr", data);
|
||||
cmd.Add("c", "");
|
||||
cmd.Add("p", obj);
|
||||
return NetworkObject.WrapObject(1, 13, cmd).Serialize();
|
||||
}
|
||||
}
|
||||
|
168
src/Core/WorldEvent.cs
Normal file
168
src/Core/WorldEvent.cs
Normal file
@ -0,0 +1,168 @@
|
||||
using System.Globalization;
|
||||
using sodoffmmo.Data;
|
||||
|
||||
namespace sodoffmmo.Core;
|
||||
class WorldEvent {
|
||||
private static WorldEvent _instance = null;
|
||||
private object EventLock = new object();
|
||||
private Random random = new Random();
|
||||
|
||||
public static WorldEvent Get() {
|
||||
if (_instance == null) {
|
||||
_instance = new WorldEvent();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
private WorldEvent() {
|
||||
Reset(0.5f);
|
||||
}
|
||||
|
||||
private string uid;
|
||||
private Room room;
|
||||
private DateTime startTime;
|
||||
private DateTime endTime;
|
||||
private string startTimeString;
|
||||
private Dictionary<string, float> health;
|
||||
private Dictionary<Client, string> players;
|
||||
private Client operatorAI;
|
||||
private DateTime AITime;
|
||||
private bool endTimeIsSet;
|
||||
|
||||
private void Reset(float time) {
|
||||
startTime = DateTime.UtcNow.AddMinutes(time);
|
||||
startTimeString = startTime.ToString("MM/dd/yyyy HH:mm:ss");
|
||||
uid = Path.GetRandomFileName().Substring(0, 8); // this is used as RandomSeed for random select ship variant
|
||||
room = Room.GetOrAdd("HubTrainingDO");
|
||||
endTime = startTime.AddMinutes(10);
|
||||
endTimeIsSet = false;
|
||||
operatorAI = null;
|
||||
health = new();
|
||||
players = new();
|
||||
}
|
||||
|
||||
private void InitEvent() {
|
||||
lock (EventLock) {
|
||||
if (operatorAI is null || AITime < DateTime.UtcNow) {
|
||||
var clients = room.Clients.ToList();
|
||||
operatorAI = clients[random.Next(0, clients.Count)];
|
||||
AITime = DateTime.UtcNow.AddSeconds(3.5);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
operatorAI.Send(Utils.VlNetworkPacket("WE__AI", operatorAI.PlayerData.Uid));
|
||||
Console.WriteLine($"Event AI operator: {operatorAI.PlayerData.Uid}");
|
||||
}
|
||||
|
||||
private bool EndEvent(bool force = false) {
|
||||
bool results = true;
|
||||
string targets = "";
|
||||
foreach (var x in health) {
|
||||
results = results && (x.Value == 0.0f);
|
||||
targets += x.Key + ":" + x.Value.ToString("0.0#####", CultureInfo.GetCultureInfo("en-US")) + ",";
|
||||
}
|
||||
if (results || force) {
|
||||
string scores = "";
|
||||
foreach (var x in players) {
|
||||
scores += x.Value + ",";
|
||||
}
|
||||
|
||||
NetworkPacket packet = Utils.VlNetworkPacket(
|
||||
"WE_ScoutAttack_End",
|
||||
$"{uid};{results};{scores};{targets}"
|
||||
);
|
||||
foreach (var roomClient in room.Clients) {
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
|
||||
NetworkObject wedata = new();
|
||||
NetworkArray vl = new();
|
||||
NetworkArray vl1 = new();
|
||||
vl1.Add("WE__AI");
|
||||
vl1.Add((Byte)0);
|
||||
vl1.Add("");
|
||||
vl1.Add(false);
|
||||
vl1.Add(false);
|
||||
vl.Add(vl1);
|
||||
foreach (var t in health) {
|
||||
NetworkArray vl2 = new();
|
||||
vl2.Add("WEH_" + t.Key);
|
||||
vl2.Add((Byte)0);
|
||||
vl2.Add("");
|
||||
vl2.Add(false);
|
||||
vl2.Add(false);
|
||||
vl.Add(vl2);
|
||||
NetworkArray vl3 = new();
|
||||
vl3.Add("WEF_" + t.Key);
|
||||
vl3.Add((Byte)0);
|
||||
vl3.Add("");
|
||||
vl3.Add(false);
|
||||
vl3.Add(false);
|
||||
vl.Add(vl3);
|
||||
}
|
||||
wedata.Add("r", room.Id);
|
||||
wedata.Add("vl", vl);
|
||||
packet = NetworkObject.WrapObject(0, 11, wedata).Serialize();
|
||||
|
||||
Reset(5);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public string EventInfo() {
|
||||
return startTimeString + "," + uid + ", false, HubTrainingDO";
|
||||
}
|
||||
|
||||
public string EventInfoNext() {
|
||||
return startTimeString; // TODO on og this was different time (real next event?)
|
||||
}
|
||||
|
||||
public string GetUid() => uid;
|
||||
|
||||
public Room GetRoom() => room;
|
||||
|
||||
public float UpdateHealth(string targetUid, float updateVal) {
|
||||
InitEvent(); // TODO better place for this
|
||||
|
||||
if (!health.ContainsKey(targetUid))
|
||||
health.Add(targetUid, 1.0f);
|
||||
health[targetUid] -= updateVal;
|
||||
|
||||
if (health[targetUid] < 0) {
|
||||
health[targetUid] = 0.0f;
|
||||
if (EndEvent())
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
if (endTime < DateTime.UtcNow) {
|
||||
EndEvent(true);
|
||||
return -1.0f;
|
||||
}
|
||||
|
||||
return health[targetUid];
|
||||
}
|
||||
|
||||
public void UpdateScore(Client client, string value) {
|
||||
if (!players.ContainsKey(client)) {
|
||||
players.Add(client, value);
|
||||
} else {
|
||||
players[client] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateAI(Client client) {
|
||||
if (client == operatorAI)
|
||||
AITime = DateTime.UtcNow.AddSeconds(7);
|
||||
}
|
||||
|
||||
public void SetTimeSpan(Client client, float seconds) {
|
||||
if (client == operatorAI || !endTimeIsSet) {
|
||||
endTime = startTime.AddSeconds(seconds);
|
||||
endTimeIsSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
public float GetHealth(string targetUid) => health[targetUid];
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user