diff --git a/src/Core/WorldEvent.cs b/src/Core/WorldEvent.cs index 9d7aade..950b57b 100644 --- a/src/Core/WorldEvent.cs +++ b/src/Core/WorldEvent.cs @@ -22,7 +22,11 @@ class WorldEvent { } private WorldEvent() { - Reset(10); + startTime = DateTime.UtcNow.AddMinutes(-60); + startTimeString = startTime.ToString("MM/dd/yyyy HH:mm:ss"); + uid = "sodoff"; + state = State.End; + ScheduleEvent(10); // WE_ != WEN_ } // controlled (init/reset) by Reset() @@ -33,16 +37,19 @@ class WorldEvent { private DateTime startTime; private DateTime endTime; - private string startTimeString; + private DateTime nextStartTime; private DateTime AITime; private bool endTimeIsSet; + private string startTimeString; + private string nextStartTimeString; // controlled (init/reset) by InitEvent() private Dictionary health = new(); private Dictionary players = new(); private string lastResults = ""; - private void Reset(float time) { + // reset event - set new id, start time, end time, etc + private void Reset(float time = 2) { lock (EventLock) { room = Room.GetOrAdd("HubTrainingDO"); uid = Path.GetRandomFileName().Substring(0, 8); // this is used as RandomSeed for random select ship variant @@ -55,33 +62,37 @@ class WorldEvent { UpdateEndTime(600 + 90); endTimeIsSet = false; + nextStartTime = startTime; + nextStartTimeString = startTimeString; + Console.WriteLine($"Event {uid} start time: {startTimeString}"); } } + // set / update event end time in results of Reset() or SetTimeSpan() private void UpdateEndTime(double timeout) { endTime = startTime.AddSeconds(timeout); Console.WriteLine($"Event {uid} end time: {endTime}"); - ResetTimer((endTime - DateTime.UtcNow).TotalSeconds); - timer.Elapsed += PreEndEvent; + SetTimer((endTime - DateTime.UtcNow).TotalSeconds, PreEndEvent); } - private void ResetTimer(double timeout) { - if (timer != null) { - timer.Stop(); - timer.Close(); - } - - timer = new System.Timers.Timer(timeout * 1000); - timer.AutoReset = false; - timer.Enabled = true; - - Console.WriteLine($"Event {uid} reset timer set to {timeout} s"); + // schedule next event and set timer to call PreInit + private void ScheduleEvent(float minutes) { + nextStartTime = DateTime.UtcNow.AddMinutes(minutes); + nextStartTimeString = nextStartTime.ToString("MM/dd/yyyy HH:mm:ss");; + SetTimer(minutes*60 - 120, PreInit); } + // reset event and set timer to call PreEndEvent, send new WE_ info + private void PreInit(Object source, ElapsedEventArgs e) { + Reset(); // WE_ == WEN_ + AnnounceEvent(); + } + + // check init state and init event (set AI, reset health, score) if need in response to client (shot, etc) request private void InitEvent() { lock (EventLock) { - if (AITime < DateTime.UtcNow) { + if (AITime < DateTime.UtcNow && state != State.End) { var clients = room.Clients.ToList(); operatorAI = clients[random.Next(0, clients.Count)]; AITime = DateTime.UtcNow.AddSeconds(3.5); @@ -128,6 +139,17 @@ class WorldEvent { } lastResults = $"{uid};{results};{scores};{targets}"; + Console.WriteLine($"Event {uid} end: {results} {targets} {scores}"); + + SetTimer(2, PostEndEvent1); // looks like client don't like get _End before WEH_ with 0.0 ... so wait to send _End + + return true; + } + return false; + } + + // send reward info + private void PostEndEvent1(Object source, ElapsedEventArgs e) { NetworkPacket packet = Utils.VlNetworkPacket( "WE_ScoutAttack_End", lastResults, @@ -137,8 +159,6 @@ class WorldEvent { roomClient.Send(packet); } - Console.WriteLine($"Event {uid} end: {results} {targets} {scores}"); - NetworkArray vl = new(); NetworkArray vl1 = new(); vl1.Add("WE__AI"); @@ -168,48 +188,67 @@ class WorldEvent { roomClient.Send(packet); } - // (re)schedule event reset and announcement of next event - ResetTimer(60); - timer.Elapsed += PostEndEvent; - - return true; - } - return false; + Console.WriteLine($"Event {uid} sent _End"); + + SetTimer(60, PostEndEvent2); } - private void PostEndEvent(Object source, ElapsedEventArgs e) { - Reset(30); + // schedule next event, set timer to call PreInit() and send new WEN_ info + private void PostEndEvent2(Object source, ElapsedEventArgs e) { + ScheduleEvent(30); // WE_ != WEN_ + AnnounceEvent(false, true); // send only WEN_ (WE_ should stay unchanged ... as WE_..._End) + } + + // set server side timer for word event state changes + private void SetTimer(double timeout, System.Timers.ElapsedEventHandler callback) { + if (timer != null) { + timer.Stop(); + timer.Close(); + } - Console.WriteLine($"Event {uid} send event notification (WE_ + WEN_) to all clients"); - NetworkPacket packet = Utils.VlNetworkPacket(EventInfoArray(), room.Id); + timer = new System.Timers.Timer(timeout * 1000); + timer.AutoReset = false; + timer.Enabled = true; + timer.Elapsed += callback; + + Console.WriteLine($"Event timer {callback.Method.Name} set to {timeout} s"); + } + + // send event info + private void AnnounceEvent(bool WE = true, bool WEN = true) { + Console.WriteLine($"Event {uid} send event notification (WE_ = {(WE ? startTimeString : WE)} WEN_ = {(WEN ? nextStartTimeString : WEN)}, room = {room.Id}) to all clients"); + NetworkPacket packet = Utils.VlNetworkPacket(EventInfoArray(WE, WEN), room.Id); foreach (var r in Room.AllRooms()) { foreach (var roomClient in r.Clients) { roomClient.Send(packet); } } } - public string EventInfo() { return startTimeString + "," + uid + ", false, HubTrainingDO"; } - public NetworkArray EventInfoArray(bool x = false) { + public NetworkArray EventInfoArray(bool WE = true, bool WEN = true) { NetworkArray vl = new(); - NetworkArray vl1 = new(); - vl1.Add("WE_ScoutAttack"); - vl1.Add((Byte)4); - vl1.Add(EventInfo()); - vl1.Add(false); - vl1.Add(x); - vl.Add(vl1); - NetworkArray vl2 = new(); - vl2.Add("WEN_ScoutAttack"); - vl2.Add((Byte)4); - vl2.Add(startTimeString); - vl2.Add(false); - vl2.Add(x); - vl.Add(vl2); + if (WE) { + NetworkArray vl1 = new(); + vl1.Add("WE_ScoutAttack"); + vl1.Add((Byte)4); + vl1.Add(EventInfo()); + vl1.Add(false); + vl1.Add(true); + vl.Add(vl1); + } + if (WEN) { + NetworkArray vl2 = new(); + vl2.Add("WEN_ScoutAttack"); + vl2.Add((Byte)4); + vl2.Add(nextStartTimeString); + vl2.Add(false); + vl2.Add(true); + vl.Add(vl2); + } return vl; } @@ -232,7 +271,7 @@ class WorldEvent { health.Add(targetUid, 1.0f); health[targetUid] -= updateVal; - if (health[targetUid] < 0) { + if (health[targetUid] < 0.0001f) { health[targetUid] = 0.0f; EndEvent(); } @@ -245,6 +284,17 @@ class WorldEvent { return health[targetUid]; } + public void SetTimeSpan(Client client, float seconds) { + if (state != State.Active) { + return; + } + if (client == operatorAI || !endTimeIsSet) { + Console.WriteLine($"Event {uid} set TimeSpan: {seconds} from operator: {client == operatorAI}"); + UpdateEndTime(seconds); + endTimeIsSet = true; + } + } + public void UpdateScore(string client, string value) { if (!players.ContainsKey(client)) { players.Add(client, value); @@ -257,25 +307,10 @@ class WorldEvent { if (client == operatorAI) AITime = DateTime.UtcNow.AddSeconds(7); } - - public void SetTimeSpan(Client client, float seconds) { - if (state != State.Active) { - return; - } - if (client == operatorAI || !endTimeIsSet) { - Console.WriteLine($"Event {uid} set TimeSpan: {seconds} from operator: {client == operatorAI}"); - UpdateEndTime(seconds); - endTimeIsSet = true; - } - } public float GetHealth(string targetUid) => health[targetUid]; - public bool IsActive() { - return state == State.Active; - } + public bool IsActive() => (state == State.Active); - public string GetLastResults() { - return lastResults; - } + public string GetLastResults() => lastResults; }