Protected Collection (Pro)
Important information can be not only within basic data types such as integer or float, but also within collections. AntiCheat provides protected alternatives for commonly used collections such as List, Queue and Stack, allowing you to monitor changes and check their integrity.
Protected List
A protected list is similar to the normal generic list you would use, with the special feature that its integrity is checked. How is this done? Each time you get, add or set an element, the list calculates a hash over its data. This hash will be used to check the integrity of the list and validate that it got not tampered with.
Another special feature is that the protected lists only allow data that is stored as a value (structs) and not as a reference (classes). This ensures that the list elements cannot be indirectly manipulated by you, which would lead to an accidental integrity problem, even if it is meant to be. However, you can of course also allow data by reference if you wish.
Typical situations where you might use a list include:
- Player inventory: A list can be used to store the items that a player has collected or is carrying.
- High scores: A list can be employed to keep track of the top scores achieved by players.
- Quest objectives: A list can be useful for storing the objectives or tasks that a player needs to complete during a quest.
Depending on the game scenario, this data might being worth to be protected and watched. To do so, use the ProtectedList
Using a ProtectedList might look like this: Note: A protected list does not automatically notify a detector of possible tampering, as an integrity check on each access based on the scenario could be far too performance-intensive. Therefore, perform the check manually if you believe it is necessary. A protected queue is similar to the normal generic queue you would use, with the special feature that its integrity is checked. How is this done? Each time you get, add or set an element, the queue calculates a hash over its data. This hash will be used to check the integrity of the queue and validate that it got not tampered with. Another special feature is that the protected queues only allow data that is stored as a value (structs) and not as a reference (classes). This ensures that the queue elements cannot be indirectly manipulated by you, which would lead to an accidental integrity problem, even if it is meant to be. However, you can of course also allow data by reference if you wish. Typical situations where you might use a queue include: Depending on the game scenario, this data might being worth to be protected and watched. To do so, use the ProtectedQueue
Using a ProtectedQueue might look like this: Note: A protected queue does not automatically notify a detector of possible tampering, as an integrity check on each access based on the scenario could be far too performance-intensive. Therefore, perform the check manually if you believe it is necessary. A protected stack is similar to the normal generic stack you would use, with the special feature that its integrity is checked. How is this done? Each time you get, add or set an element, the stack calculates a hash over its data. This hash will be used to check the integrity of the queue and validate that it got not tampered with. Another special feature is that the protected stacks only allow data that is stored as a value (structs) and not as a reference (classes). This ensures that the stack elements cannot be indirectly manipulated by you, which would lead to an accidental integrity problem, even if it is meant to be. However, you can of course also allow data by reference if you wish. Typical situations where you might use a stack include: Using a ProtectedStack might look like this: Note: A protected stack does not automatically notify a detector of possible tampering, as an integrity check on each access based on the scenario could be far too performance-intensive. Therefore, perform the check manually if you believe it is necessary./// <summary>
/// Represents a protected list that implements the <see cref="IList{T}"/> interface. This list allows tracking changes
/// and provides a hash code for verification purposes. Before interacting with the list, you should call the <see cref="CheckIntegrity"/>
/// method to verify its integrity.
/// </summary>
/// <typeparam name="T">The type of elements in the list.</typeparam>
public class ProtectedList<T> : IList<T>, IDataIntegrity where T : struct
// Create a new protected list.
ProtectedList<Int32> protectedList = new ProtectedList<Int32>();
// Fill it with data.
protectedList.Add(1);
protectedList.Add(2);
protectedList.Add(3);
// Verify its integrity.
if(protectedList.CheckIntegrity())
{
// Has still its integrity, do some calculation and send it to the server.
// ... TODO: Put your code here.
}
else
{
// Has no longer its integrity, probably caused through memory manipulation.
// ... TODO: Put your code here.
}
Protected Queue
/// <summary>
/// Represents a protected queue that implements the <see cref="IEnumerable{T}"/>, <see cref="IEnumerable"/>,
/// <see cref="IReadOnlyCollection{T}"/>, and <see cref="ICollection"/> interfaces. This queue allows tracking changes and
/// provides a hash code for verification purposes. Before interacting with the queue, you should call the <see cref="CheckIntegrity"/>
/// to verify its integrity.
/// </summary>
/// <typeparam name="T">The type of elements in the queue.</typeparam>
public class ProtectedQueue<T> : IEnumerable<T>, IEnumerable, IReadOnlyCollection<T>, ICollection, IDataIntegrity where T : struct
// Create a new protected queue.
ProtectedQueue<Int32> protectedQueue = new ProtectedQueue<Int32>();
// Fill it with data.
protectedQueue.Enqueue(1);
protectedQueue.Enqueue(2);
protectedQueue.Enqueue(3);
// Verify its integrity.
if(protectedQueue.CheckIntegrity())
{
// Has still its integrity, do some calculation and send it to the server.
// ... TODO: Put your code here.
}
else
{
// Has no longer its integrity, probably caused through memory manipulation.
// ... TODO: Put your code here.
}
Protected Stack
/// <summary>
/// Represents a protected stack that implements the <see cref="IEnumerable{T}"/>, <see cref="IEnumerable"/>,
/// <see cref="IReadOnlyCollection{T}"/>, and <see cref="ICollection"/> interfaces. This stack allows tracking changes
/// and provides a hash code for verification purposes. Before interacting with the stack, you should call the <see cref="CheckIntegrity"/>
/// to verify its integrity.
/// </summary>
/// <typeparam name="T">The type of elements in the stack.</typeparam>
public class ProtectedStack<T> : IEnumerable<T>, IEnumerable, IReadOnlyCollection<T>, ICollection, IDataIntegrity where T : struct
// Create a new protected stack.
ProtectedStack<Int32> protectedStack = new ProtectedStack<Int32>();
// Fill it with data.
protectedStack.Push(1);
protectedStack.Push(2);
protectedStack.Push(3);
// Verify its integrity.
if(protectedStack.CheckIntegrity())
{
// Has still its integrity, do some calculation and send it to the server.
// ... TODO: Put your code here.
}
else
{
// Has no longer its integrity, probably caused through memory manipulation.
// ... TODO: Put your code here.
}