1414using Chaos . Networking . Abstractions ;
1515using Chaos . Networking . Abstractions . Definitions ;
1616using Chaos . Networking . Entities . Server ;
17+ using Chaos . NLog . Logging . Definitions ;
18+ using Chaos . NLog . Logging . Extensions ;
1719using Chaos . Packets ;
1820using Chaos . Packets . Abstractions ;
1921
2830using Darkages . Managers ;
2931using Darkages . Meta ;
3032using Darkages . Models ;
33+ using Darkages . Network . Client . Abstractions ;
3134using Darkages . Network . Client . Coalescer ;
3235using Darkages . Network . Server ;
3336using Darkages . Object ;
@@ -156,12 +159,10 @@ public bool IsDayDreaming
156159 public WorldPortal PendingNode { get ; set ; }
157160 public uint EntryCheck { get ; set ; }
158161 private readonly Lock _warpCheckLock = new ( ) ;
159- private readonly ConcurrentQueue < ExperienceEvent > _expQueue = [ ] ;
160- private readonly ConcurrentQueue < AbilityEvent > _apQueue = [ ] ;
161- private readonly ConcurrentQueue < DebuffEvent > _debuffApplyQueue = [ ] ;
162- private readonly ConcurrentQueue < BuffEvent > _buffApplyQueue = [ ] ;
163- private readonly ConcurrentQueue < DebuffEvent > _debuffUpdateQueue = [ ] ;
164- private readonly ConcurrentQueue < BuffEvent > _buffUpdateQueue = [ ] ;
162+
163+ // Client-owned work queue
164+ private readonly ConcurrentQueue < IClientWork > _clientWorkQueue = new ( ) ;
165+ private readonly SemaphoreSlim _clientWorkSignal = new ( 0 , int . MaxValue ) ;
165166
166167 public WorldClient ( [ NotNull ] IWorldServer < IWorldClient > server , [ NotNull ] Socket socket ,
167168 [ NotNull ] ICrypto crypto , [ NotNull ] IPacketSerializer packetSerializer ,
@@ -171,14 +172,7 @@ public WorldClient([NotNull] IWorldServer<IWorldClient> server, [NotNull] Socket
171172 _soundCoalescer = new SoundCoalescer ( SendSoundImmediate , 150 , 24 ) ;
172173 _healthBarCoalescer = new HealthBarCoalescer ( SendHealthBarCoalesced , 150 , 24 ) ;
173174 _bodyAnimationCoalescer = new BodyAnimationCoalescer ( SendBodyAnimationCoalesced , 150 , 24 ) ;
174-
175- // Event-Driven Tasks
176- _ = Task . Factory . StartNew ( ProcessExperienceEvents , CancellationToken . None , TaskCreationOptions . LongRunning , TaskScheduler . Default ) . Unwrap ( ) ;
177- _ = Task . Factory . StartNew ( ProcessAbilityEvents , CancellationToken . None , TaskCreationOptions . LongRunning , TaskScheduler . Default ) . Unwrap ( ) ;
178- _ = Task . Factory . StartNew ( ProcessApplyingBuffsEvents , CancellationToken . None , TaskCreationOptions . LongRunning , TaskScheduler . Default ) . Unwrap ( ) ;
179- _ = Task . Factory . StartNew ( ProcessApplyingDebuffsEvents , CancellationToken . None , TaskCreationOptions . LongRunning , TaskScheduler . Default ) . Unwrap ( ) ;
180- _ = Task . Factory . StartNew ( ProcessUpdatingBuffsEvents , CancellationToken . None , TaskCreationOptions . LongRunning , TaskScheduler . Default ) . Unwrap ( ) ;
181- _ = Task . Factory . StartNew ( ProcessUpdatingDebuffsEvents , CancellationToken . None , TaskCreationOptions . LongRunning , TaskScheduler . Default ) . Unwrap ( ) ;
175+ _ = Task . Run ( ProcessPlayerWorkQueue ) ;
182176 }
183177
184178 public Task Update ( )
@@ -199,113 +193,6 @@ public Task Update()
199193 return Task . CompletedTask ;
200194 }
201195
202-
203- #region Events
204-
205- private async Task ProcessExperienceEvents ( )
206- {
207- while ( ServerSetup . Instance . Running )
208- {
209- if ( _expQueue . IsEmpty )
210- {
211- await Task . Delay ( 50 ) . ConfigureAwait ( false ) ;
212- continue ;
213- }
214-
215- while ( _expQueue . TryDequeue ( out var expEvent ) )
216- {
217- HandleExp ( expEvent . Player , expEvent . Exp , expEvent . Hunting ) ;
218- }
219- }
220- }
221-
222- private async Task ProcessAbilityEvents ( )
223- {
224- while ( ServerSetup . Instance . Running )
225- {
226- if ( _apQueue . IsEmpty )
227- {
228- await Task . Delay ( 50 ) . ConfigureAwait ( false ) ;
229- continue ;
230- }
231-
232- while ( _apQueue . TryDequeue ( out var apEvent ) )
233- {
234- HandleAp ( apEvent . Player , apEvent . Exp , apEvent . Hunting ) ;
235- }
236- }
237- }
238-
239- private async Task ProcessApplyingDebuffsEvents ( )
240- {
241- while ( ServerSetup . Instance . Running )
242- {
243- if ( _debuffApplyQueue . IsEmpty )
244- {
245- await Task . Delay ( 50 ) . ConfigureAwait ( false ) ;
246- continue ;
247- }
248-
249- while ( _debuffApplyQueue . TryDequeue ( out var debuffEvent ) )
250- {
251- debuffEvent . Debuff . OnApplied ( debuffEvent . Affected , debuffEvent . Debuff ) ;
252- }
253- }
254- }
255-
256- private async Task ProcessApplyingBuffsEvents ( )
257- {
258- while ( ServerSetup . Instance . Running )
259- {
260- if ( _buffApplyQueue . IsEmpty )
261- {
262- await Task . Delay ( 50 ) . ConfigureAwait ( false ) ;
263- continue ;
264- }
265-
266- while ( _buffApplyQueue . TryDequeue ( out var buffEvent ) )
267- {
268- buffEvent . Buff . OnApplied ( buffEvent . Affected , buffEvent . Buff ) ;
269- }
270- }
271- }
272-
273- private async Task ProcessUpdatingDebuffsEvents ( )
274- {
275- while ( ServerSetup . Instance . Running )
276- {
277- if ( _debuffUpdateQueue . IsEmpty )
278- {
279- await Task . Delay ( 50 ) . ConfigureAwait ( false ) ;
280- continue ;
281- }
282-
283- while ( _debuffUpdateQueue . TryDequeue ( out var debuffEvent ) )
284- {
285- debuffEvent . Debuff . Update ( debuffEvent . Affected ) ;
286- }
287- }
288- }
289-
290- private async Task ProcessUpdatingBuffsEvents ( )
291- {
292- while ( ServerSetup . Instance . Running )
293- {
294- if ( _buffUpdateQueue . IsEmpty )
295- {
296- await Task . Delay ( 50 ) . ConfigureAwait ( false ) ;
297- continue ;
298- }
299-
300- while ( _buffUpdateQueue . TryDequeue ( out var buffEvent ) )
301- {
302- buffEvent . Buff . Update ( buffEvent . Affected ) ;
303- }
304- }
305- }
306-
307- #endregion
308-
309196 private void CheckInvisible ( Aisling player , Stopwatch sw )
310197 {
311198 if ( player . IsInvisible ) return ;
@@ -4069,14 +3956,71 @@ public static void KillPlayer(Area map, string u)
40693956
40703957 #endregion
40713958
4072- #region Events & Experience
3959+ #region Client Work Queue
3960+
3961+ private async Task ProcessPlayerWorkQueue ( )
3962+ {
3963+ while ( ServerSetup . Instance . Running )
3964+ {
3965+ await _clientWorkSignal . WaitAsync ( 5000 ) . ConfigureAwait ( false ) ;
3966+
3967+ while ( _clientWorkQueue . TryDequeue ( out var work ) )
3968+ {
3969+ try
3970+ {
3971+ work . Execute ( this ) ;
3972+ }
3973+ catch { }
3974+ }
3975+ }
3976+ }
3977+
3978+ public void EnqueueExperienceEvent ( Aisling player , long exp , bool hunting )
3979+ {
3980+ _clientWorkQueue . Enqueue ( new ExperienceEvent ( player , exp , hunting ) ) ;
3981+ _clientWorkSignal . Release ( ) ;
3982+ }
3983+
3984+ public void EnqueueAbilityEvent ( Aisling player , int exp , bool hunting )
3985+ {
3986+ _clientWorkQueue . Enqueue ( new AbilityEvent ( player , exp , hunting ) ) ;
3987+ _clientWorkSignal . Release ( ) ;
3988+ }
3989+
3990+ public void EnqueueDebuffAppliedEvent ( Sprite affected , Debuff debuff )
3991+ {
3992+ _clientWorkQueue . Enqueue ( new DebuffOnAppliedEvent ( affected , debuff ) ) ;
3993+ _clientWorkSignal . Release ( ) ;
3994+ }
3995+
3996+ public void EnqueueDebuffUpdatedEvent ( Sprite affected , Debuff debuff )
3997+ {
3998+ _clientWorkQueue . Enqueue ( new DebuffOnUpdatedEvent ( affected , debuff ) ) ;
3999+ _clientWorkSignal . Release ( ) ;
4000+ }
4001+
4002+ public void EnqueueBuffAppliedEvent ( Sprite affected , Buff buff )
4003+ {
4004+ _clientWorkQueue . Enqueue ( new BuffOnAppliedEvent ( affected , buff ) ) ;
4005+ _clientWorkSignal . Release ( ) ;
4006+ }
40734007
4074- public void EnqueueExperienceEvent ( Aisling player , long exp , bool hunting ) => _expQueue . Enqueue ( new ExperienceEvent ( player , exp , hunting ) ) ;
4075- public void EnqueueAbilityEvent ( Aisling player , int exp , bool hunting ) => _apQueue . Enqueue ( new AbilityEvent ( player , exp , hunting ) ) ;
4076- public void EnqueueDebuffAppliedEvent ( Sprite affected , Debuff debuff ) => _debuffApplyQueue . Enqueue ( new DebuffEvent ( affected , debuff ) ) ;
4077- public void EnqueueBuffAppliedEvent ( Sprite affected , Buff buff ) => _buffApplyQueue . Enqueue ( new BuffEvent ( affected , buff ) ) ;
4078- public void EnqueueDebuffUpdatedEvent ( Sprite affected , Debuff debuff ) => _debuffUpdateQueue . Enqueue ( new DebuffEvent ( affected , debuff ) ) ;
4079- public void EnqueueBuffUpdatedEvent ( Sprite affected , Buff buff ) => _buffUpdateQueue . Enqueue ( new BuffEvent ( affected , buff ) ) ;
4008+ public void EnqueueBuffUpdatedEvent ( Sprite affected , Buff buff )
4009+ {
4010+ _clientWorkQueue . Enqueue ( new BuffOnUpdatedEvent ( affected , buff ) ) ;
4011+ _clientWorkSignal . Release ( ) ;
4012+ }
4013+
4014+ internal void ClientWorkExpEvent ( Aisling player , long exp , bool hunting ) => HandleExp ( player , exp , hunting ) ;
4015+ internal void ClientWorkApEvent ( Aisling player , int exp , bool hunting ) => HandleAp ( player , exp , hunting ) ;
4016+ internal void ClientWorkDebuffAppliedEvent ( Sprite affected , Debuff debuff ) => debuff . OnApplied ( affected , debuff ) ;
4017+ internal void ClientWorkDebuffUpdatedEvent ( Sprite affected , Debuff debuff ) => debuff . Update ( affected ) ;
4018+ internal void ClientWorkBuffAppliedEvent ( Sprite affected , Buff buff ) => buff . OnApplied ( affected , buff ) ;
4019+ internal void ClientWorkBuffUpdatedEvent ( Sprite affected , Buff buff ) => buff . Update ( affected ) ;
4020+
4021+ #endregion
4022+
4023+ #region Events & Experience
40804024
40814025 public void GiveExp ( long exp )
40824026 {
0 commit comments