forked from FabianTerhorst/coreclr-module
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathClient.cs
More file actions
145 lines (120 loc) · 4.52 KB
/
Client.cs
File metadata and controls
145 lines (120 loc) · 4.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
using System.Collections.Generic;
using System.Numerics;
namespace AltV.Net.EntitySync
{
//TODO: make client dirty when position or dimension changes, only check dirty characters in entity thread
//TODO: this requires to calculate stream out somehow
//TODO: dirty clients can only calculate stream outs and position changes
/// <summary>
/// A client is a connected peer that authenticated itself via a token.
/// In most cases the client contains a IPlayer object and gets the position and exists status out of this.
/// </summary>
public class Client : IClient
{
public string Token { get; }
public virtual Vector3 Position { get; set; }
public virtual int Dimension { get; set; }
public ClientDataSnapshot Snapshot { get; }
public virtual bool Exists { get; } = true;
private Vector3 positionOverride;
private bool isPositionOverwritten;
/// <summary>
/// List of entities this client has ever seen and set to true if created.
/// </summary>
private readonly Dictionary<IEntity, bool>[] entities;
/// <summary>
/// List of entities that this client had created last time, so we can calculate when a entity is not in range of this client anymore.
/// </summary>
private readonly IDictionary<IEntity, bool>[] lastCheckedEntities;
public Client(ulong threadCount, string token)
{
Snapshot = new ClientDataSnapshot(threadCount);
entities = new Dictionary<IEntity, bool>[threadCount];
for (ulong i = 0; i < threadCount; i++)
{
entities[i] = new Dictionary<IEntity, bool>();
}
lastCheckedEntities = new IDictionary<IEntity, bool>[threadCount];
for (ulong i = 0; i < threadCount; i++)
{
lastCheckedEntities[i] = new Dictionary<IEntity, bool>();
}
Token = token;
}
public virtual bool TryGetDimensionAndPosition(out int dimension, ref Vector3 position)
{
lock (this)
{
if (isPositionOverwritten)
{
position = positionOverride;
}
else
{
position = Position;
}
dimension = Dimension;
}
return true;
}
public virtual void SetPositionOverride(Vector3 newPositionOverride)
{
lock (this)
{
positionOverride = newPositionOverride;
isPositionOverwritten = true;
}
}
public virtual void ResetPositionOverride()
{
lock (this)
{
isPositionOverwritten = false;
}
}
/// <summary>
/// Tries to add a entity to the list of entities that this client got created.
/// </summary>
/// <param name="threadIndex"></param>
/// <param name="entity"></param>
/// <returns>true of entity wasn't created</returns>
public bool TryAddEntity(ulong threadIndex, IEntity entity)
{
var threadEntities = entities[threadIndex];
if (threadEntities.TryGetValue(entity, out var state))
{
if (state) return false; // already created
threadEntities[entity] = true;
return true;
}
threadEntities[entity] = true;
return true;
}
public void RemoveEntity(ulong threadIndex, IEntity entity)
{
lastCheckedEntities[threadIndex].Remove(entity);
entities[threadIndex][entity] = false;
}
public void RemoveEntityFully(ulong threadIndex, IEntity entity)
{
lastCheckedEntities[threadIndex].Remove(entity);
entities[threadIndex].Remove(entity);
}
public void AddCheck(ulong threadIndex, IEntity entity)
{
lastCheckedEntities[threadIndex][entity] = true;
}
public void RemoveCheck(ulong threadIndex, IEntity entity)
{
lastCheckedEntities[threadIndex][entity] = false;
}
public IDictionary<IEntity, bool> GetLastCheckedEntities(ulong threadIndex)
{
return lastCheckedEntities[threadIndex];
}
public Dictionary<IEntity, bool> GetEntities(ulong threadIndex)
{
return entities[threadIndex];
}
}
}