2017-11-25 20:29:58 -05:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2018-08-03 22:11:58 -04:00
|
|
|
|
using System.ComponentModel;
|
2017-11-25 20:29:58 -05:00
|
|
|
|
using System.ComponentModel.DataAnnotations.Schema;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
2018-04-08 02:44:42 -04:00
|
|
|
|
namespace SharedLibraryCore.Objects
|
2017-11-29 19:35:50 -05:00
|
|
|
|
{
|
2017-11-25 20:29:58 -05:00
|
|
|
|
public class Player : Database.Models.EFClient
|
|
|
|
|
{
|
2018-06-30 21:55:16 -04:00
|
|
|
|
public enum ClientState
|
|
|
|
|
{
|
2018-08-27 18:07:54 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// represents when the client has been detected as joining
|
|
|
|
|
/// by the log file, but has not be authenticated by RCon
|
|
|
|
|
/// </summary>
|
2018-06-30 21:55:16 -04:00
|
|
|
|
Connecting,
|
2018-08-27 18:07:54 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// represents when the client has been parsed by RCon,
|
|
|
|
|
/// but has not been validated against the database
|
|
|
|
|
/// </summary>
|
|
|
|
|
Authenticated,
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// represents when the client has been authenticated by RCon
|
|
|
|
|
/// and validated by the database
|
|
|
|
|
/// </summary>
|
2018-06-30 21:55:16 -04:00
|
|
|
|
Connected,
|
2018-08-27 18:07:54 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// represents when the client is leaving (either through RCon or log file)
|
|
|
|
|
/// </summary>
|
2018-06-30 21:55:16 -04:00
|
|
|
|
Disconnecting,
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-25 20:29:58 -05:00
|
|
|
|
public enum Permission
|
|
|
|
|
{
|
2018-09-02 17:59:27 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// client has been banned
|
|
|
|
|
/// </summary>
|
2017-11-25 20:29:58 -05:00
|
|
|
|
Banned = -1,
|
2018-09-02 17:59:27 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// default client state upon first connect
|
|
|
|
|
/// </summary>
|
2017-11-25 20:29:58 -05:00
|
|
|
|
User = 0,
|
2018-09-02 17:59:27 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// client has been flagged
|
|
|
|
|
/// </summary>
|
2017-11-25 20:29:58 -05:00
|
|
|
|
Flagged = 1,
|
2018-09-02 17:59:27 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// client is trusted
|
|
|
|
|
/// </summary>
|
2017-11-25 20:29:58 -05:00
|
|
|
|
Trusted = 2,
|
2018-09-02 17:59:27 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// client is a moderator
|
|
|
|
|
/// </summary>
|
2017-11-25 20:29:58 -05:00
|
|
|
|
Moderator = 3,
|
2018-09-02 17:59:27 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// client is an administrator
|
|
|
|
|
/// </summary>
|
2017-11-25 20:29:58 -05:00
|
|
|
|
Administrator = 4,
|
2018-09-02 17:59:27 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// client is a senior administrator
|
|
|
|
|
/// </summary>
|
2017-11-25 20:29:58 -05:00
|
|
|
|
SeniorAdmin = 5,
|
2018-09-02 17:59:27 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// client is a owner
|
|
|
|
|
/// </summary>
|
2017-11-25 20:29:58 -05:00
|
|
|
|
Owner = 6,
|
2018-09-02 17:59:27 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// not used
|
|
|
|
|
/// </summary>
|
2017-11-25 20:29:58 -05:00
|
|
|
|
Creator = 7,
|
2018-09-02 17:59:27 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// reserved for default account
|
|
|
|
|
/// </summary>
|
2018-08-03 22:11:58 -04:00
|
|
|
|
Console = 8
|
2017-11-25 20:29:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Player()
|
|
|
|
|
{
|
|
|
|
|
ConnectionTime = DateTime.UtcNow;
|
2017-11-29 19:35:50 -05:00
|
|
|
|
ClientNumber = -1;
|
2018-07-04 22:09:42 -04:00
|
|
|
|
DelayedEvents = new Queue<GameEvent>();
|
2018-09-02 17:59:27 -04:00
|
|
|
|
_additionalProperties = new Dictionary<string, object>();
|
2017-11-25 20:29:58 -05:00
|
|
|
|
}
|
2017-11-29 19:35:50 -05:00
|
|
|
|
|
2018-09-02 17:59:27 -04:00
|
|
|
|
public override string ToString() => $"{Name}::{NetworkId}";
|
2017-11-25 20:29:58 -05:00
|
|
|
|
|
2018-09-29 15:52:22 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// send a message directly to the connected client
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="message">message content to send to client</param>
|
|
|
|
|
public GameEvent Tell(String message)
|
2017-11-25 20:29:58 -05:00
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
var e = new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Message = message,
|
|
|
|
|
Target = this,
|
|
|
|
|
Owner = CurrentServer,
|
|
|
|
|
Type = GameEvent.EventType.Tell,
|
|
|
|
|
Data = message
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// warn a client with given reason
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="warnReason">reason for warn</param>
|
|
|
|
|
/// <param name="sender">client performing the warn</param>
|
|
|
|
|
public GameEvent Warn(String warnReason, Player sender)
|
|
|
|
|
{
|
|
|
|
|
var e = new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.Warn,
|
|
|
|
|
Message = warnReason,
|
|
|
|
|
Origin = sender,
|
|
|
|
|
Target = this,
|
|
|
|
|
Owner = this.CurrentServer
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// enforce level restrictions
|
|
|
|
|
if (sender.Level <= this.Level)
|
|
|
|
|
{
|
|
|
|
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-29 22:49:12 -04:00
|
|
|
|
this.Warnings++;
|
|
|
|
|
|
2018-09-29 15:52:22 -04:00
|
|
|
|
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// report a client for a given reason
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="reportReason">reason for the report</param>
|
|
|
|
|
/// <param name="sender">client performing the report</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public GameEvent Report(string reportReason, Player sender)
|
|
|
|
|
{
|
|
|
|
|
var e = new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.Report,
|
|
|
|
|
Message = reportReason,
|
|
|
|
|
Data = reportReason,
|
|
|
|
|
Origin = sender,
|
|
|
|
|
Target = this,
|
|
|
|
|
Owner = this.CurrentServer
|
|
|
|
|
};
|
|
|
|
|
|
2018-09-29 22:49:12 -04:00
|
|
|
|
if (this.Level > sender.Level)
|
2018-09-29 15:52:22 -04:00
|
|
|
|
{
|
|
|
|
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (this == sender)
|
|
|
|
|
{
|
|
|
|
|
e.FailReason = GameEvent.EventFailReason.Invalid;
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-29 22:49:12 -04:00
|
|
|
|
if (CurrentServer.Reports.Count(rep => (rep.Origin.NetworkId == sender.NetworkId &&
|
2018-09-29 15:52:22 -04:00
|
|
|
|
rep.Target.NetworkId == this.NetworkId)) > 0)
|
|
|
|
|
{
|
|
|
|
|
e.FailReason = GameEvent.EventFailReason.Exception;
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-29 22:49:12 -04:00
|
|
|
|
CurrentServer.Reports.Add(new Report(this, sender, reportReason));
|
2018-09-29 15:52:22 -04:00
|
|
|
|
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
|
|
|
|
return e;
|
2017-11-25 20:29:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
2018-09-29 15:52:22 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// clear all warnings for a client
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="sender">client performing the warn clear</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public GameEvent WarnClear(Player sender)
|
2017-11-25 20:29:58 -05:00
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
var e = new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.WarnClear,
|
|
|
|
|
Origin = sender,
|
|
|
|
|
Target = this,
|
|
|
|
|
Owner = this.CurrentServer
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// enforce level restrictions
|
|
|
|
|
if (sender.Level <= this.Level)
|
|
|
|
|
{
|
|
|
|
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.Warnings = 0;
|
|
|
|
|
|
|
|
|
|
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// flag a client for a given reason
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="flagReason">reason for flagging</param>
|
|
|
|
|
/// <param name="sender">client performing the flag</param>
|
|
|
|
|
/// <returns>game event for the flag</returns>
|
|
|
|
|
public GameEvent Flag(string flagReason, Player sender)
|
|
|
|
|
{
|
|
|
|
|
var e = new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.Flag,
|
|
|
|
|
Origin = sender,
|
|
|
|
|
Data = flagReason,
|
|
|
|
|
Message = flagReason,
|
|
|
|
|
Owner = this.CurrentServer
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (sender.Level <= this.Level)
|
2018-05-10 01:34:29 -04:00
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
|
|
|
|
return e;
|
2018-05-10 01:34:29 -04:00
|
|
|
|
}
|
2018-05-08 00:58:46 -04:00
|
|
|
|
|
2018-09-29 15:52:22 -04:00
|
|
|
|
if (this.Level == Player.Permission.Flagged)
|
2018-05-04 00:22:10 -04:00
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
e.FailReason = GameEvent.EventFailReason.Invalid;
|
|
|
|
|
return e;
|
|
|
|
|
}
|
2018-05-04 00:22:10 -04:00
|
|
|
|
|
2018-09-29 15:52:22 -04:00
|
|
|
|
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// unflag a client for a given reason
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="unflagReason">reason to unflag a player for</param>
|
|
|
|
|
/// <param name="sender">client performing the unflag</param>
|
|
|
|
|
/// <returns>game event for the un flug</returns>
|
|
|
|
|
public GameEvent Unflag(string unflagReason, Player sender)
|
|
|
|
|
{
|
|
|
|
|
var e = new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.Unflag,
|
|
|
|
|
Origin = sender,
|
|
|
|
|
Data = unflagReason,
|
|
|
|
|
Message = unflagReason,
|
|
|
|
|
Owner = this.CurrentServer
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (sender.Level <= this.Level)
|
|
|
|
|
{
|
|
|
|
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
|
|
|
|
return e;
|
2018-05-10 01:34:29 -04:00
|
|
|
|
}
|
2018-09-29 15:52:22 -04:00
|
|
|
|
|
|
|
|
|
if (this.Level != Player.Permission.Flagged)
|
|
|
|
|
{
|
|
|
|
|
e.FailReason = GameEvent.EventFailReason.Invalid;
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.Level = Permission.User;
|
|
|
|
|
|
|
|
|
|
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
|
|
|
|
return e;
|
2017-11-25 20:29:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
2018-09-29 15:52:22 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// kick a client for the given reason
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="kickReason">reason to kick for</param>
|
|
|
|
|
/// <param name="sender">client performing the kick</param>
|
|
|
|
|
public GameEvent Kick(String kickReason, Player sender)
|
2017-11-25 20:29:58 -05:00
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
var e = new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.Kick,
|
|
|
|
|
Message = kickReason,
|
|
|
|
|
Target = this,
|
|
|
|
|
Origin = sender,
|
|
|
|
|
Data = kickReason,
|
|
|
|
|
Owner = this.CurrentServer
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// enforce level restrictions
|
|
|
|
|
if (sender.Level <= this.Level)
|
|
|
|
|
{
|
|
|
|
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
|
|
|
|
return e;
|
2017-11-25 20:29:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
2018-09-29 15:52:22 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// temporarily ban a client for the given time span
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="tempbanReason">reason for the temp ban</param>
|
|
|
|
|
/// <param name="banLength">how long the temp ban lasts</param>
|
|
|
|
|
/// <param name="sender">client performing the tempban</param>
|
|
|
|
|
public GameEvent TempBan(String tempbanReason, TimeSpan banLength, Player sender)
|
2017-11-25 20:29:58 -05:00
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
var e = new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.TempBan,
|
|
|
|
|
Message = tempbanReason,
|
|
|
|
|
Origin = sender,
|
|
|
|
|
Target = this,
|
|
|
|
|
Extra = banLength,
|
|
|
|
|
Owner = this.CurrentServer
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// enforce level restrictions
|
|
|
|
|
if (sender.Level <= this.Level)
|
|
|
|
|
{
|
|
|
|
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
|
|
|
|
return e;
|
2017-11-25 20:29:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
2018-09-29 15:52:22 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// permanently ban a client
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="banReason">reason for the ban</param>
|
|
|
|
|
/// <param name="sender">client performing the ban</param>
|
|
|
|
|
public GameEvent Ban(String banReason, Player sender)
|
2017-11-25 20:29:58 -05:00
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
var e = new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.Ban,
|
|
|
|
|
Message = banReason,
|
|
|
|
|
Origin = sender,
|
|
|
|
|
Target = this,
|
|
|
|
|
Owner = this.CurrentServer
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// enforce level restrictions
|
|
|
|
|
if (sender.Level <= this.Level)
|
|
|
|
|
{
|
|
|
|
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
|
|
|
|
return e;
|
2017-11-25 20:29:58 -05:00
|
|
|
|
}
|
|
|
|
|
|
2018-09-29 15:52:22 -04:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// unban a client
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="unbanReason">reason for the unban</param>
|
|
|
|
|
/// <param name="sender">client performing the unban</param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public GameEvent Unban(String unbanReason, Player sender)
|
2017-11-25 20:29:58 -05:00
|
|
|
|
{
|
2018-09-29 15:52:22 -04:00
|
|
|
|
var e = new GameEvent()
|
|
|
|
|
{
|
|
|
|
|
Type = GameEvent.EventType.Unban,
|
|
|
|
|
Message = unbanReason,
|
|
|
|
|
Data = unbanReason,
|
|
|
|
|
Origin = sender,
|
|
|
|
|
Target = this,
|
|
|
|
|
Owner = this.CurrentServer
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// enforce level restrictions
|
|
|
|
|
if (sender.Level <= this.Level)
|
|
|
|
|
{
|
|
|
|
|
e.FailReason = GameEvent.EventFailReason.Permission;
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CurrentServer.Manager.GetEventHandler().AddEvent(e);
|
|
|
|
|
return e;
|
2017-11-25 20:29:58 -05:00
|
|
|
|
}
|
2018-09-29 15:52:22 -04:00
|
|
|
|
|
2018-09-02 17:59:27 -04:00
|
|
|
|
[NotMapped]
|
|
|
|
|
Dictionary<string, object> _additionalProperties;
|
|
|
|
|
public T GetAdditionalProperty<T>(string name) => (T)_additionalProperties[name];
|
|
|
|
|
public void SetAdditionalProperty(string name, object value) => _additionalProperties.Add(name, value);
|
2017-11-25 20:29:58 -05:00
|
|
|
|
[NotMapped]
|
2017-11-29 19:35:50 -05:00
|
|
|
|
public int ClientNumber { get; set; }
|
2017-11-25 20:29:58 -05:00
|
|
|
|
[NotMapped]
|
|
|
|
|
public int Ping { get; set; }
|
|
|
|
|
[NotMapped]
|
|
|
|
|
public int Warnings { get; set; }
|
|
|
|
|
[NotMapped]
|
|
|
|
|
public DateTime ConnectionTime { get; set; }
|
|
|
|
|
[NotMapped]
|
2018-09-07 23:29:42 -04:00
|
|
|
|
public int ConnectionLength => (int)(DateTime.UtcNow - ConnectionTime).TotalSeconds;
|
|
|
|
|
[NotMapped]
|
2017-11-25 20:29:58 -05:00
|
|
|
|
public Server CurrentServer { get; set; }
|
2018-02-09 02:21:25 -05:00
|
|
|
|
[NotMapped]
|
|
|
|
|
public int Score { get; set; }
|
2018-02-14 14:01:26 -05:00
|
|
|
|
[NotMapped]
|
2018-04-15 21:27:43 -04:00
|
|
|
|
public bool IsBot { get; set; }
|
2018-02-10 23:33:42 -05:00
|
|
|
|
private int _ipaddress;
|
|
|
|
|
public override int IPAddress
|
2017-11-29 19:35:50 -05:00
|
|
|
|
{
|
|
|
|
|
get { return _ipaddress; }
|
|
|
|
|
set { _ipaddress = value; }
|
|
|
|
|
}
|
|
|
|
|
private string _name;
|
|
|
|
|
public override string Name
|
|
|
|
|
{
|
|
|
|
|
get { return _name; }
|
2018-08-03 22:11:58 -04:00
|
|
|
|
set { _name = value; }
|
2017-11-29 19:35:50 -05:00
|
|
|
|
}
|
2018-06-30 21:55:16 -04:00
|
|
|
|
[NotMapped]
|
|
|
|
|
public ClientState State { get; set; }
|
2018-07-04 22:09:42 -04:00
|
|
|
|
[NotMapped]
|
|
|
|
|
public Queue<GameEvent> DelayedEvents { get; set; }
|
2018-08-03 22:11:58 -04:00
|
|
|
|
[NotMapped]
|
|
|
|
|
// this is kinda dirty, but I need localizable level names
|
|
|
|
|
public ClientPermission ClientPermission => new ClientPermission()
|
|
|
|
|
{
|
|
|
|
|
Level = Level,
|
|
|
|
|
Name = Utilities.CurrentLocalization
|
|
|
|
|
.LocalizationIndex[$"GLOBAL_PERMISSION_{Level.ToString().ToUpper()}"]
|
|
|
|
|
};
|
2018-02-10 23:33:42 -05:00
|
|
|
|
|
|
|
|
|
public override bool Equals(object obj)
|
|
|
|
|
{
|
|
|
|
|
return ((Player)obj).NetworkId == NetworkId;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-02 17:59:27 -04:00
|
|
|
|
public override int GetHashCode() => (int)NetworkId;
|
2017-11-25 20:29:58 -05:00
|
|
|
|
}
|
|
|
|
|
}
|