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) {
|
public void Handle(Client client, NetworkObject receivedObject) {
|
||||||
NetworkObject cmd = new();
|
NetworkObject cmd = new();
|
||||||
NetworkObject obj = 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("c", "DT");
|
||||||
cmd.Add("p", obj);
|
cmd.Add("p", obj);
|
||||||
client.Send(NetworkObject.WrapObject(1, 13, cmd).Serialize());
|
client.Send(NetworkObject.WrapObject(1, 13, cmd).Serialize());
|
||||||
|
@ -14,9 +14,7 @@ class JoinRoomHandler : ICommandHandler
|
|||||||
string roomName = receivedObject.Get<NetworkObject>("p").Get<string>("rn");
|
string roomName = receivedObject.Get<NetworkObject>("p").Get<string>("rn");
|
||||||
client.LeaveRoom();
|
client.LeaveRoom();
|
||||||
client.InvalidatePlayerData();
|
client.InvalidatePlayerData();
|
||||||
if (!Room.Exists(roomName))
|
room = Room.GetOrAdd(roomName);
|
||||||
Room.Add(roomName);
|
|
||||||
room = Room.Get(roomName);
|
|
||||||
Console.WriteLine($"Join Room: {roomName} RoomID: {room.Id} IID: {client.ClientID}");
|
Console.WriteLine($"Join Room: {roomName} RoomID: {room.Id} IID: {client.ClientID}");
|
||||||
this.client = client;
|
this.client = client;
|
||||||
|
|
||||||
@ -103,4 +101,4 @@ class JoinRoomHandler : ICommandHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,25 @@ class LoginHandler : ICommandHandler
|
|||||||
|
|
||||||
NetworkArray r2 = new();
|
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(1);
|
||||||
r2.Add("ADMIN");
|
r2.Add("ADMIN");
|
||||||
r2.Add("default");
|
r2.Add("default");
|
||||||
@ -36,7 +55,7 @@ class LoginHandler : ICommandHandler
|
|||||||
r2.Add(true);
|
r2.Add(true);
|
||||||
r2.Add((short)0);
|
r2.Add((short)0);
|
||||||
r2.Add((short)1);
|
r2.Add((short)1);
|
||||||
r2.Add(new NetworkArray());
|
r2.Add(we);
|
||||||
rl.Add(r2);
|
rl.Add(r2);
|
||||||
|
|
||||||
NetworkArray r3 = new();
|
NetworkArray r3 = new();
|
||||||
@ -61,4 +80,4 @@ class LoginHandler : ICommandHandler
|
|||||||
|
|
||||||
client.Send(NetworkObject.WrapObject(0, 1, content).Serialize());
|
client.Send(NetworkObject.WrapObject(0, 1, content).Serialize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
@ -38,6 +38,12 @@ public class Room {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static Room Get(string name) => rooms[name];
|
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 bool Exists(string name) => rooms.ContainsKey(name);
|
||||||
|
|
||||||
|
@ -5,6 +5,8 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
using sodoffmmo.Data;
|
||||||
|
|
||||||
namespace sodoffmmo.Core;
|
namespace sodoffmmo.Core;
|
||||||
internal static class Utils {
|
internal static class Utils {
|
||||||
public static bool VariablesValid(Client client) {
|
public static bool VariablesValid(Client client) {
|
||||||
@ -19,4 +21,32 @@ internal static class Utils {
|
|||||||
}
|
}
|
||||||
return true;
|
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