Update latency detection method
Plus some server code refactoring
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Core;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@ -48,7 +49,6 @@ namespace RageCoop.Client
|
||||
AutoFlushSendQueue = false
|
||||
};
|
||||
|
||||
config.EnableMessageType(NetIncomingMessageType.ConnectionLatencyUpdated);
|
||||
config.EnableMessageType(NetIncomingMessageType.UnconnectedData);
|
||||
|
||||
|
||||
@ -66,6 +66,7 @@ namespace RageCoop.Client
|
||||
throw new Exception("Malformed URL");
|
||||
}
|
||||
|
||||
PlayerList.Cleanup();
|
||||
EntityPool.AddPlayer();
|
||||
Task.Run(() =>
|
||||
{
|
||||
@ -112,7 +113,6 @@ namespace RageCoop.Client
|
||||
get { return Client?.ConnectionStatus == NetConnectionStatus.Connected; }
|
||||
}
|
||||
|
||||
#region -- GET --
|
||||
#region -- PLAYER --
|
||||
private static void PlayerConnect(Packets.PlayerConnect packet)
|
||||
{
|
||||
@ -137,6 +137,7 @@ namespace RageCoop.Client
|
||||
}
|
||||
|
||||
#endregion // -- PLAYER --
|
||||
#region -- GET --
|
||||
|
||||
private static bool GetServerPublicKey(string address, int timeout = 10000)
|
||||
{
|
||||
@ -146,8 +147,8 @@ namespace RageCoop.Client
|
||||
Client.SendUnconnectedMessage(msg, adds[0], int.Parse(adds[1]));
|
||||
return _publicKeyReceived.WaitOne(timeout);
|
||||
}
|
||||
#endregion
|
||||
internal static void GetResponse<T>(Packet request, Action<T> callback, ConnectionChannel channel = ConnectionChannel.RequestResponse) where T : Packet, new()
|
||||
|
||||
public static void GetResponse<T>(Packet request, Action<T> callback, ConnectionChannel channel = ConnectionChannel.RequestResponse) where T : Packet, new()
|
||||
{
|
||||
var received = new AutoResetEvent(false);
|
||||
var id = NewRequestID();
|
||||
@ -163,6 +164,8 @@ namespace RageCoop.Client
|
||||
request.Pack(msg);
|
||||
Client.SendMessage(msg, NetDeliveryMethod.ReliableOrdered, (int)channel);
|
||||
}
|
||||
|
||||
#endregion
|
||||
private static int NewRequestID()
|
||||
{
|
||||
int ID = 0;
|
||||
|
@ -54,7 +54,6 @@ namespace RageCoop.Client
|
||||
{
|
||||
CoopMenu.ConnectedMenuSetting();
|
||||
Main.MainChat.Init();
|
||||
PlayerList.Cleanup();
|
||||
GTA.UI.Notification.Show("~g~Connected!");
|
||||
});
|
||||
|
||||
@ -64,9 +63,6 @@ namespace RageCoop.Client
|
||||
Memory.RestorePatches();
|
||||
DownloadManager.Cleanup();
|
||||
|
||||
// Reset all values
|
||||
Latency = 0;
|
||||
|
||||
Main.QueueAction(() => Main.CleanUpWorld());
|
||||
|
||||
if (Main.MainChat.Focused)
|
||||
@ -148,9 +144,6 @@ namespace RageCoop.Client
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NetIncomingMessageType.ConnectionLatencyUpdated:
|
||||
Latency = message.ReadFloat();
|
||||
break;
|
||||
case NetIncomingMessageType.UnconnectedData:
|
||||
{
|
||||
var packetType = (PacketType)message.ReadByte();
|
||||
|
@ -45,21 +45,21 @@ namespace RageCoop.Client
|
||||
_lastUpdate = Util.GetTickCount64();
|
||||
|
||||
_mainScaleform.CallFunction("SET_DATA_SLOT_EMPTY", 0);
|
||||
_mainScaleform.CallFunction("SET_DATA_SLOT", 0, $"{Networking.Latency * 1000:N0}ms", localUsername, 116, 0, 0, "", "", 2, "", "", ' ');
|
||||
|
||||
int i = 1;
|
||||
|
||||
int i=0;
|
||||
|
||||
foreach (var player in Players)
|
||||
{
|
||||
_mainScaleform.CallFunction("SET_DATA_SLOT", i++, $"{player.Value.Latency * 1000:N0}ms", player.Value.Username, 116, 0, i - 1, "", "", 2, "", "", ' ');
|
||||
}
|
||||
|
||||
_mainScaleform.CallFunction("SET_TITLE", "Player list", $"{Players.Count+1} players");
|
||||
_mainScaleform.CallFunction("SET_TITLE", "Player list", $"{Players.Count} players");
|
||||
_mainScaleform.CallFunction("DISPLAY_VIEW");
|
||||
}
|
||||
public static void SetPlayer(int id, string username, float latency = 0)
|
||||
{
|
||||
|
||||
if(id == Main.LocalPlayerID) { Networking.Latency=latency; }
|
||||
Main.Logger.Debug($"{id},{username},{latency}");
|
||||
PlayerData p;
|
||||
if (Players.TryGetValue(id, out p))
|
||||
{
|
||||
|
@ -350,7 +350,7 @@ namespace RageCoop.Client
|
||||
void DisplayVehicle()
|
||||
{
|
||||
var current = MainVehicle.ReadPosition();
|
||||
var predicted = Position+Velocity*(SyncParameters.PositioinPredictionDefault+0.001f*LastSyncedStopWatch.ElapsedMilliseconds);
|
||||
var predicted = Position+Velocity*(Networking.Latency+0.001f*LastSyncedStopWatch.ElapsedMilliseconds);
|
||||
if (current.DistanceTo(Position)<5)
|
||||
{
|
||||
MainVehicle.Velocity = Velocity+5*(predicted - current);
|
||||
|
64
RageCoop.Core/Packets/ChatMessage.cs
Normal file
64
RageCoop.Core/Packets/ChatMessage.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
|
||||
internal partial class Packets
|
||||
{
|
||||
|
||||
internal class ChatMessage : Packet
|
||||
{
|
||||
private Func<string, byte[]> crypt;
|
||||
private Func<byte[], byte[]> decrypt;
|
||||
public ChatMessage(Func<string, byte[]> crypter)
|
||||
{
|
||||
crypt = crypter;
|
||||
}
|
||||
public ChatMessage(Func<byte[], byte[]> decrypter)
|
||||
{
|
||||
decrypt = decrypter;
|
||||
}
|
||||
public string Username { get; set; }
|
||||
|
||||
public string Message { get; set; }
|
||||
|
||||
public override void Pack(NetOutgoingMessage message)
|
||||
{
|
||||
#region PacketToNetOutGoingMessage
|
||||
message.Write((byte)PacketType.ChatMessage);
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
|
||||
|
||||
// Write Username
|
||||
byteArray.AddString(Username);
|
||||
|
||||
|
||||
// Write Message
|
||||
byteArray.AddArray(crypt(Message));
|
||||
|
||||
byte[] result = byteArray.ToArray();
|
||||
|
||||
message.Write(result.Length);
|
||||
message.Write(result);
|
||||
#endregion
|
||||
}
|
||||
|
||||
public override void Unpack(byte[] array)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
// Read username
|
||||
int usernameLength = reader.ReadInt();
|
||||
Username = reader.ReadString(usernameLength);
|
||||
|
||||
Message = decrypt(reader.ReadByteArray()).GetString();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
26
RageCoop.Core/Packets/Misc.cs
Normal file
26
RageCoop.Core/Packets/Misc.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
internal partial class Packets
|
||||
{
|
||||
internal class PingPong : Packet
|
||||
{
|
||||
|
||||
public override void Pack(NetOutgoingMessage message)
|
||||
{
|
||||
#region PacketToNetOutGoingMessage
|
||||
message.Write((byte)PacketType.ChatMessage);
|
||||
message.Write(0);
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public override void Unpack(byte[] array)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -73,7 +73,8 @@ namespace RageCoop.Core
|
||||
File = 8,
|
||||
Event = 9,
|
||||
RequestResponse=10,
|
||||
VehicleSync=20,
|
||||
PingPong = 11,
|
||||
VehicleSync =20,
|
||||
PedSync=21,
|
||||
ProjectileSync = 22,
|
||||
SyncEvents =30,
|
||||
@ -150,62 +151,6 @@ namespace RageCoop.Core
|
||||
public abstract void Unpack(byte[] array);
|
||||
}
|
||||
|
||||
internal partial class Packets
|
||||
{
|
||||
|
||||
internal class ChatMessage : Packet
|
||||
{
|
||||
private Func<string, byte[]> crypt;
|
||||
private Func<byte[], byte[]> decrypt;
|
||||
public ChatMessage(Func<string,byte[]> crypter)
|
||||
{
|
||||
crypt = crypter;
|
||||
}
|
||||
public ChatMessage(Func<byte[], byte[]> decrypter)
|
||||
{
|
||||
decrypt = decrypter;
|
||||
}
|
||||
public string Username { get; set; }
|
||||
|
||||
public string Message { get; set; }
|
||||
|
||||
public override void Pack(NetOutgoingMessage message)
|
||||
{
|
||||
#region PacketToNetOutGoingMessage
|
||||
message.Write((byte)PacketType.ChatMessage);
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
|
||||
|
||||
// Write Username
|
||||
byteArray.AddString(Username);
|
||||
|
||||
|
||||
// Write Message
|
||||
byteArray.AddArray(crypt(Message));
|
||||
|
||||
byte[] result = byteArray.ToArray();
|
||||
|
||||
message.Write(result.Length);
|
||||
message.Write(result);
|
||||
#endregion
|
||||
}
|
||||
|
||||
public override void Unpack(byte[] array)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
// Read username
|
||||
int usernameLength = reader.ReadInt();
|
||||
Username = reader.ReadString(usernameLength);
|
||||
|
||||
Message = decrypt(reader.ReadByteArray()).GetString();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class CoopSerializer
|
||||
{
|
||||
|
@ -2,8 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using RageCoop.Core;
|
||||
using Lidgren.Network;
|
||||
using System.Linq;
|
||||
using GTA;
|
||||
using System.Diagnostics;
|
||||
using RageCoop.Core.Scripting;
|
||||
using System.Security.Cryptography;
|
||||
using RageCoop.Server.Scripting;
|
||||
@ -60,6 +59,7 @@ namespace RageCoop.Server
|
||||
}
|
||||
|
||||
private bool _displayNameTag=true;
|
||||
private Stopwatch _latencyWatch = new Stopwatch();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether to enable automatic respawn for this client's main ped.
|
||||
@ -73,40 +73,21 @@ namespace RageCoop.Server
|
||||
_displayNameTag=value;
|
||||
}
|
||||
}
|
||||
#region CUSTOMDATA FUNCTIONS
|
||||
/*
|
||||
public void SetData<T>(string name, T data)
|
||||
internal void UpdateLatency()
|
||||
{
|
||||
if (HasData(name))
|
||||
_latencyWatch.Restart();
|
||||
Server.GetResponse<Packets.PingPong>(this, new Packets.PingPong(), ConnectionChannel.PingPong);
|
||||
_latencyWatch.Stop();
|
||||
Latency = (float)_latencyWatch.ElapsedMilliseconds/2000;
|
||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||
new Packets.PlayerInfoUpdate()
|
||||
{
|
||||
_customData[name] = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
_customData.Add(name, data);
|
||||
}
|
||||
PedID=Player.ID,
|
||||
Username=Username,
|
||||
Latency=Latency,
|
||||
}.Pack(outgoingMessage);
|
||||
Server.MainNetServer.SendToAll(outgoingMessage, NetDeliveryMethod.ReliableSequenced, (byte)ConnectionChannel.Default);
|
||||
}
|
||||
|
||||
public bool HasData(string name)
|
||||
{
|
||||
return _customData.ContainsKey(name);
|
||||
}
|
||||
|
||||
public T GetData<T>(string name)
|
||||
{
|
||||
return HasData(name) ? (T)_customData[name] : default;
|
||||
}
|
||||
|
||||
public void RemoveData(string name)
|
||||
{
|
||||
if (HasData(name))
|
||||
{
|
||||
_customData.Remove(name);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#endregion
|
||||
#region FUNCTIONS
|
||||
/// <summary>
|
||||
/// Kick this client
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Linq;
|
||||
@ -51,10 +52,10 @@ namespace RageCoop.Server
|
||||
internal Resources Resources;
|
||||
internal Logger Logger;
|
||||
private Security Security;
|
||||
private System.Timers.Timer _sendInfoTimer = new System.Timers.Timer(5000);
|
||||
private bool _stopping = false;
|
||||
private Thread _listenerThread;
|
||||
private Thread _announceThread;
|
||||
private Thread _latencyThread;
|
||||
private Worker _worker;
|
||||
private Dictionary<int,Action<PacketType,byte[]>> PendingResponses=new();
|
||||
internal Dictionary<PacketType, Func<byte[],Client,Packet>> RequestHandlers=new();
|
||||
@ -76,7 +77,125 @@ namespace RageCoop.Server
|
||||
Security=new Security(Logger);
|
||||
Entities=new ServerEntities(this);
|
||||
BaseScript=new BaseScript(this);
|
||||
|
||||
_worker=new Worker("ServerWorker", Logger);
|
||||
|
||||
_listenerThread=new Thread(() => Listen());
|
||||
_latencyThread=new Thread(() =>
|
||||
{
|
||||
while (!_stopping)
|
||||
{
|
||||
foreach(var c in Clients.Values)
|
||||
{
|
||||
c.UpdateLatency();
|
||||
}
|
||||
Thread.Sleep(3000);
|
||||
}
|
||||
});
|
||||
_announceThread=new Thread(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// TLS only
|
||||
ServicePointManager.Expect100Continue = true;
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls13 | SecurityProtocolType.Tls12;
|
||||
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
|
||||
|
||||
HttpClient httpClient = new();
|
||||
|
||||
IpInfo info;
|
||||
try
|
||||
{
|
||||
HttpResponseMessage response = await httpClient.GetAsync("https://ipinfo.io/json");
|
||||
if (response.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
throw new Exception($"IPv4 request failed! [{(int)response.StatusCode}/{response.ReasonPhrase}]");
|
||||
}
|
||||
|
||||
string content = await response.Content.ReadAsStringAsync();
|
||||
info = JsonConvert.DeserializeObject<IpInfo>(content);
|
||||
Logger?.Info($"Your public IP is {info.Address}, announcing to master server...");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger?.Error(ex.InnerException?.Message ?? ex.Message);
|
||||
return;
|
||||
}
|
||||
while (!_stopping)
|
||||
{
|
||||
string msg =
|
||||
"{ " +
|
||||
"\"address\": \"" + info.Address + "\", " +
|
||||
"\"port\": \"" + Settings.Port + "\", " +
|
||||
"\"country\": \"" + info.Country + "\", " +
|
||||
"\"name\": \"" + Settings.Name + "\", " +
|
||||
"\"version\": \"" + _compatibleVersion.Replace("_", ".") + "\", " +
|
||||
"\"players\": \"" + MainNetServer.ConnectionsCount + "\", " +
|
||||
"\"maxPlayers\": \"" + Settings.MaxPlayers + "\", " +
|
||||
"\"description\": \"" + Settings.Description + "\", " +
|
||||
"\"website\": \"" + Settings.Website + "\", " +
|
||||
"\"gameMode\": \"" + Settings.GameMode + "\", " +
|
||||
"\"language\": \"" + Settings.Language + "\"" +
|
||||
" }";
|
||||
HttpResponseMessage response = null;
|
||||
try
|
||||
{
|
||||
var realUrl = Util.GetFinalRedirect(Settings.MasterServer);
|
||||
response = await httpClient.PostAsync(realUrl, new StringContent(msg, Encoding.UTF8, "application/json"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger?.Error($"MasterServer: {ex.Message}");
|
||||
|
||||
// Sleep for 5s
|
||||
Thread.Sleep(5000);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (response == null)
|
||||
{
|
||||
Logger?.Error("MasterServer: Something went wrong!");
|
||||
}
|
||||
else if (response.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
if (response.StatusCode == HttpStatusCode.BadRequest)
|
||||
{
|
||||
string requestContent = await response.Content.ReadAsStringAsync();
|
||||
Logger?.Error($"MasterServer: [{(int)response.StatusCode}], {requestContent}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger?.Error($"MasterServer: [{(int)response.StatusCode}]");
|
||||
Logger?.Error($"MasterServer: [{await response.Content.ReadAsStringAsync()}]");
|
||||
}
|
||||
}
|
||||
|
||||
// Sleep for 10s
|
||||
for (int i = 0; i<10; i++)
|
||||
{
|
||||
if (_stopping)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
Logger?.Error($"MasterServer: {ex.InnerException.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger?.Error($"MasterServer: {ex.Message}");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Spawn threads and start the server
|
||||
/// </summary>
|
||||
@ -98,129 +217,22 @@ namespace RageCoop.Server
|
||||
};
|
||||
|
||||
config.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
|
||||
config.EnableMessageType(NetIncomingMessageType.ConnectionLatencyUpdated);
|
||||
config.EnableMessageType(NetIncomingMessageType.UnconnectedData);
|
||||
|
||||
MainNetServer = new NetServer(config);
|
||||
MainNetServer.Start();
|
||||
_worker=new Worker("ServerWorker",Logger);
|
||||
_sendInfoTimer.Elapsed+=(s, e) => { SendPlayerInfos(); };
|
||||
_sendInfoTimer.AutoReset=true;
|
||||
_sendInfoTimer.Enabled=true;
|
||||
Logger?.Info(string.Format("Server listening on {0}:{1}", config.LocalAddress.ToString(), config.Port));
|
||||
if (Settings.AnnounceSelf)
|
||||
{
|
||||
|
||||
#region -- MASTERSERVER --
|
||||
_announceThread=new Thread(async () =>
|
||||
{
|
||||
try
|
||||
{
|
||||
// TLS only
|
||||
ServicePointManager.Expect100Continue = true;
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls13 | SecurityProtocolType.Tls12 ;
|
||||
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
|
||||
|
||||
HttpClient httpClient = new();
|
||||
|
||||
IpInfo info;
|
||||
try
|
||||
{
|
||||
HttpResponseMessage response = await httpClient.GetAsync("https://ipinfo.io/json");
|
||||
if (response.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
throw new Exception($"IPv4 request failed! [{(int)response.StatusCode}/{response.ReasonPhrase}]");
|
||||
}
|
||||
|
||||
string content = await response.Content.ReadAsStringAsync();
|
||||
info = JsonConvert.DeserializeObject<IpInfo>(content);
|
||||
Logger?.Info($"Your public IP is {info.Address}, announcing to master server...");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger?.Error(ex.InnerException?.Message ?? ex.Message);
|
||||
return;
|
||||
}
|
||||
while (!_stopping)
|
||||
{
|
||||
string msg =
|
||||
"{ " +
|
||||
"\"address\": \"" + info.Address + "\", " +
|
||||
"\"port\": \"" + Settings.Port + "\", " +
|
||||
"\"country\": \"" + info.Country + "\", " +
|
||||
"\"name\": \"" + Settings.Name + "\", " +
|
||||
"\"version\": \"" + _compatibleVersion.Replace("_", ".") + "\", " +
|
||||
"\"players\": \"" + MainNetServer.ConnectionsCount + "\", " +
|
||||
"\"maxPlayers\": \"" + Settings.MaxPlayers + "\", " +
|
||||
"\"description\": \"" + Settings.Description + "\", " +
|
||||
"\"website\": \"" + Settings.Website + "\", " +
|
||||
"\"gameMode\": \"" + Settings.GameMode + "\", " +
|
||||
"\"language\": \"" + Settings.Language + "\"" +
|
||||
" }";
|
||||
HttpResponseMessage response = null;
|
||||
try
|
||||
{
|
||||
var realUrl = Util.GetFinalRedirect(Settings.MasterServer);
|
||||
response = await httpClient.PostAsync(realUrl, new StringContent(msg, Encoding.UTF8, "application/json"));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger?.Error($"MasterServer: {ex.Message}");
|
||||
|
||||
// Sleep for 5s
|
||||
Thread.Sleep(5000);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (response == null)
|
||||
{
|
||||
Logger?.Error("MasterServer: Something went wrong!");
|
||||
}
|
||||
else if (response.StatusCode != HttpStatusCode.OK)
|
||||
{
|
||||
if (response.StatusCode == HttpStatusCode.BadRequest)
|
||||
{
|
||||
string requestContent = await response.Content.ReadAsStringAsync();
|
||||
Logger?.Error($"MasterServer: [{(int)response.StatusCode}], {requestContent}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger?.Error($"MasterServer: [{(int)response.StatusCode}]");
|
||||
Logger?.Error($"MasterServer: [{await response.Content.ReadAsStringAsync()}]");
|
||||
}
|
||||
}
|
||||
|
||||
// Sleep for 10s
|
||||
for(int i = 0; i<10; i++)
|
||||
{
|
||||
if (_stopping)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
Logger?.Error($"MasterServer: {ex.InnerException.Message}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger?.Error($"MasterServer: {ex.Message}");
|
||||
}
|
||||
});
|
||||
_announceThread.Start();
|
||||
#endregion
|
||||
}
|
||||
|
||||
BaseScript.API=API;
|
||||
BaseScript.OnStart();
|
||||
Resources.LoadAll();
|
||||
_listenerThread=new Thread(() => Listen());
|
||||
_listenerThread.Start();
|
||||
_latencyThread.Start();
|
||||
if (Settings.AnnounceSelf)
|
||||
{
|
||||
_announceThread.Start();
|
||||
}
|
||||
|
||||
Logger?.Info("Listening for clients");
|
||||
}
|
||||
/// <summary>
|
||||
@ -229,12 +241,10 @@ namespace RageCoop.Server
|
||||
public void Stop()
|
||||
{
|
||||
_stopping = true;
|
||||
_sendInfoTimer.Stop();
|
||||
_sendInfoTimer.Enabled=false;
|
||||
_sendInfoTimer.Dispose();
|
||||
Logger?.Flush();
|
||||
_listenerThread?.Join();
|
||||
_announceThread?.Join();
|
||||
_listenerThread.Join();
|
||||
_announceThread.Join();
|
||||
_latencyThread.Join();
|
||||
_worker.Dispose();
|
||||
}
|
||||
private void Listen()
|
||||
@ -386,19 +396,6 @@ namespace RageCoop.Server
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NetIncomingMessageType.ConnectionLatencyUpdated:
|
||||
{
|
||||
// Get sender client
|
||||
if (!Clients.TryGetValue(message.SenderConnection.RemoteUniqueIdentifier, out sender))
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (sender != null)
|
||||
{
|
||||
sender.Latency = message.ReadFloat();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NetIncomingMessageType.ErrorMessage:
|
||||
Logger?.Error(message.ReadString());
|
||||
break;
|
||||
@ -441,7 +438,6 @@ namespace RageCoop.Server
|
||||
|
||||
switch (type)
|
||||
{
|
||||
#region INTERVAL-SYNC
|
||||
case PacketType.PedSync:
|
||||
{
|
||||
|
||||
@ -471,9 +467,6 @@ namespace RageCoop.Server
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
case PacketType.ChatMessage:
|
||||
{
|
||||
|
||||
@ -504,28 +497,6 @@ namespace RageCoop.Server
|
||||
DisconnectAndLog(sender.Connection, type, e);
|
||||
}
|
||||
}
|
||||
object _sendPlayersLock=new object();
|
||||
internal void SendPlayerInfos()
|
||||
{
|
||||
lock (_sendPlayersLock)
|
||||
{
|
||||
foreach (Client c in Clients.Values)
|
||||
{
|
||||
MainNetServer.Connections.FindAll(x => x.RemoteUniqueIdentifier != c.NetID).ForEach(x =>
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
new Packets.PlayerInfoUpdate()
|
||||
{
|
||||
PedID=c.Player.ID,
|
||||
Username=c.Username,
|
||||
Latency=c.Latency,
|
||||
}.Pack(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, x, NetDeliveryMethod.ReliableSequenced, (byte)ConnectionChannel.Default);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void DisconnectAndLog(NetConnection senderConnection,PacketType type, Exception e)
|
||||
{
|
||||
|
Reference in New Issue
Block a user