Yet another code cleanup
This commit is contained in:
@ -1,10 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows;
|
||||
|
||||
namespace RageCoop.Client.Installer
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly:ThemeInfo(
|
||||
[assembly: ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
|
@ -1,27 +1,17 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using RageCoop.Core;
|
||||
using System.Threading;
|
||||
using System.Net;
|
||||
using System.Windows.Forms;
|
||||
using Path = System.IO.Path;
|
||||
using System.Windows.Input;
|
||||
using MessageBox = System.Windows.MessageBox;
|
||||
using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
|
||||
using Path = System.IO.Path;
|
||||
using RageCoop.Core;
|
||||
|
||||
namespace RageCoop.Client.Installer
|
||||
{
|
||||
@ -41,11 +31,12 @@ namespace RageCoop.Client.Installer
|
||||
var od = new OpenFileDialog()
|
||||
{
|
||||
Filter = "GTA 5 executable |GTA5.exe;PlayGTAV.exe",
|
||||
Title="Select you GTAV executable"
|
||||
Title = "Select you GTAV executable"
|
||||
};
|
||||
if (od.ShowDialog() ?? false == true)
|
||||
{
|
||||
Task.Run(() => {
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
Install(Directory.GetParent(od.FileName).FullName);
|
||||
@ -62,7 +53,8 @@ namespace RageCoop.Client.Installer
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
void Install(string root)
|
||||
|
||||
private void Install(string root)
|
||||
{
|
||||
UpdateStatus("Checking requirements");
|
||||
var shvPath = Path.Combine(root, "ScriptHookV.dll");
|
||||
@ -70,7 +62,7 @@ namespace RageCoop.Client.Installer
|
||||
var scriptsPath = Path.Combine(root, "Scripts");
|
||||
var lemonPath = Path.Combine(scriptsPath, "LemonUI.SHVDN3.dll");
|
||||
var installPath = Path.Combine(scriptsPath, "RageCoop");
|
||||
if(Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName == installPath)
|
||||
if (Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName == installPath)
|
||||
{
|
||||
throw new InvalidOperationException("The installer is not meant to be run in the game folder, please extract the zip to somewhere else and run again.");
|
||||
}
|
||||
@ -86,7 +78,7 @@ namespace RageCoop.Client.Installer
|
||||
Environment.Exit(1);
|
||||
}
|
||||
var shvdnVer = GetVer(shvdnPath);
|
||||
if (shvdnVer<new Version(3,5,1))
|
||||
if (shvdnVer < new Version(3, 5, 1))
|
||||
{
|
||||
MessageBox.Show("Please update ScriptHookVDotNet to latest version!" +
|
||||
$"\nCurrent version is {shvdnVer}, 3.5.1 or higher is required");
|
||||
@ -94,11 +86,11 @@ namespace RageCoop.Client.Installer
|
||||
}
|
||||
if (File.Exists(lemonPath))
|
||||
{
|
||||
var lemonVer=GetVer(lemonPath);
|
||||
if(lemonVer<new Version(1, 7))
|
||||
var lemonVer = GetVer(lemonPath);
|
||||
if (lemonVer < new Version(1, 7))
|
||||
{
|
||||
UpdateStatus("Updating LemonUI");
|
||||
File.WriteAllBytes(lemonPath,getLemon());
|
||||
File.WriteAllBytes(lemonPath, getLemon());
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,28 +136,28 @@ namespace RageCoop.Client.Installer
|
||||
}
|
||||
if (File.Exists(menyooConfig))
|
||||
{
|
||||
var lines = File.ReadAllLines(menyooConfig).Where(x => !x.StartsWith(";") && x.EndsWith(" = " +(int)settings.MenuKey));
|
||||
var lines = File.ReadAllLines(menyooConfig).Where(x => !x.StartsWith(";") && x.EndsWith(" = " + (int)settings.MenuKey));
|
||||
if (lines.Any())
|
||||
{
|
||||
if(MessageBox.Show("Following menyoo config value will conflict with RAGECOOP menu key\n" +
|
||||
if (MessageBox.Show("Following menyoo config value will conflict with RAGECOOP menu key\n" +
|
||||
string.Join("\n", lines)
|
||||
+ "\nDo you wish to change the Menu Key?", "Warning!", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
|
||||
{
|
||||
var ae=new AutoResetEvent(false);
|
||||
var ae = new AutoResetEvent(false);
|
||||
UpdateStatus("Press the key you wish to change to");
|
||||
Dispatcher.BeginInvoke(new Action(() =>
|
||||
KeyDown += (s,e) =>
|
||||
KeyDown += (s, e) =>
|
||||
{
|
||||
settings.MenuKey = (Keys)KeyInterop.VirtualKeyFromKey(e.Key);
|
||||
ae.Set();
|
||||
}));
|
||||
ae.WaitOne();
|
||||
if (!Util.SaveSettings(settingsPath,settings))
|
||||
if (!Util.SaveSettings(settingsPath, settings))
|
||||
{
|
||||
MessageBox.Show("Error occurred when saving settings");
|
||||
Environment.Exit(1);
|
||||
}
|
||||
MessageBox.Show("Menu key changed to "+settings.MenuKey);
|
||||
MessageBox.Show("Menu key changed to " + settings.MenuKey);
|
||||
goto checkKeys;
|
||||
}
|
||||
}
|
||||
@ -178,10 +170,10 @@ namespace RageCoop.Client.Installer
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (MessageBox.Show("You can't join ZeroTier server unless ZeroTier is installed, do you want to download and install it?","Install ZeroTier",MessageBoxButton.YesNo)==MessageBoxResult.Yes)
|
||||
if (MessageBox.Show("You can't join ZeroTier server unless ZeroTier is installed, do you want to download and install it?", "Install ZeroTier", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
|
||||
{
|
||||
var url = "https://download.zerotier.com/dist/ZeroTier%20One.msi";
|
||||
UpdateStatus("Downloading ZeroTier from "+url);
|
||||
UpdateStatus("Downloading ZeroTier from " + url);
|
||||
try
|
||||
{
|
||||
HttpHelper.DownloadFile(url, "ZeroTier.msi", (p) => UpdateStatus("Downloading ZeroTier " + p + "%"));
|
||||
@ -201,15 +193,18 @@ namespace RageCoop.Client.Installer
|
||||
Environment.Exit(0);
|
||||
}
|
||||
}
|
||||
void UpdateStatus(string status)
|
||||
|
||||
private void UpdateStatus(string status)
|
||||
{
|
||||
Dispatcher.BeginInvoke(new Action(() => Status.Content = status));
|
||||
}
|
||||
Version GetVer(string location)
|
||||
|
||||
private Version GetVer(string location)
|
||||
{
|
||||
return Version.Parse(FileVersionInfo.GetVersionInfo(location).FileVersion);
|
||||
}
|
||||
byte[] getLemon()
|
||||
|
||||
private byte[] getLemon()
|
||||
{
|
||||
return (byte[])Resource.ResourceManager.GetObject("LemonUI_SHVDN3");
|
||||
}
|
||||
|
@ -122,8 +122,7 @@ namespace RageCoop.Client
|
||||
{
|
||||
lock (InProgressDownloads)
|
||||
{
|
||||
DownloadFile file;
|
||||
if (InProgressDownloads.TryGetValue(id, out file))
|
||||
if (InProgressDownloads.TryGetValue(id, out DownloadFile file))
|
||||
{
|
||||
|
||||
file.Stream.Write(chunk, 0, chunk.Length);
|
||||
@ -137,9 +136,8 @@ namespace RageCoop.Client
|
||||
|
||||
public static void Complete(int id)
|
||||
{
|
||||
DownloadFile f;
|
||||
|
||||
if (InProgressDownloads.TryGetValue(id, out f))
|
||||
if (InProgressDownloads.TryGetValue(id, out DownloadFile f))
|
||||
{
|
||||
InProgressDownloads.Remove(id);
|
||||
f.Dispose();
|
||||
|
@ -142,7 +142,7 @@ namespace RageCoop.Client
|
||||
default:
|
||||
{
|
||||
|
||||
HandlePacket(packetType, message, message.SenderConnection,ref _recycle);
|
||||
HandlePacket(packetType, message, message.SenderConnection, ref _recycle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +63,7 @@ namespace RageCoop.Client
|
||||
public static void SetPlayer(int id, string username, float latency = 0)
|
||||
{
|
||||
Main.Logger.Debug($"{id},{username},{latency}");
|
||||
Player p;
|
||||
if (Players.TryGetValue(id, out p))
|
||||
if (Players.TryGetValue(id, out Player p))
|
||||
{
|
||||
p.Username = username;
|
||||
p.ID = id;
|
||||
@ -108,8 +107,7 @@ namespace RageCoop.Client
|
||||
}
|
||||
public static Player GetPlayer(int id)
|
||||
{
|
||||
Player p;
|
||||
Players.TryGetValue(id, out p);
|
||||
Players.TryGetValue(id, out Player p);
|
||||
return p;
|
||||
}
|
||||
public static Player GetPlayer(SyncedPed p)
|
||||
|
@ -16,7 +16,7 @@ using System.Resources;
|
||||
|
||||
|
||||
// Version informationr(
|
||||
[assembly: AssemblyVersion("1.5.3.188")]
|
||||
[assembly: AssemblyFileVersion("1.5.3.188")]
|
||||
[assembly: AssemblyVersion("1.5.3.191")]
|
||||
[assembly: AssemblyFileVersion("1.5.3.191")]
|
||||
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]
|
||||
|
||||
|
@ -146,8 +146,7 @@ namespace RageCoop.Client.Scripting
|
||||
|
||||
// Main.Logger.Debug($"CustomEvent:\n"+args.Args.DumpWithType());
|
||||
|
||||
List<Action<CustomEventReceivedArgs>> handlers;
|
||||
if (CustomEventHandlers.TryGetValue(p.Hash, out handlers))
|
||||
if (CustomEventHandlers.TryGetValue(p.Hash, out List<Action<CustomEventReceivedArgs>> handlers))
|
||||
{
|
||||
handlers.ForEach((x) => { x.Invoke(args); });
|
||||
}
|
||||
|
@ -127,8 +127,7 @@ namespace RageCoop.Client.Scripting
|
||||
var pos = (Vector3)obj.Args[4];
|
||||
int rot = (int)obj.Args[5];
|
||||
var name = (string)obj.Args[6];
|
||||
Blip blip;
|
||||
if (!EntityPool.ServerBlips.TryGetValue(id, out blip))
|
||||
if (!EntityPool.ServerBlips.TryGetValue(id, out Blip blip))
|
||||
{
|
||||
EntityPool.ServerBlips.Add(id, blip = World.CreateBlip(pos));
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ namespace RageCoop.Client
|
||||
CreateProjectile();
|
||||
return;
|
||||
}
|
||||
MainProjectile.Velocity = Velocity + 10*(Predict(Position) - MainProjectile.Position);
|
||||
MainProjectile.Velocity = Velocity + 10 * (Predict(Position) - MainProjectile.Position);
|
||||
MainProjectile.Rotation = Rotation;
|
||||
LastUpdated = Main.Ticked;
|
||||
}
|
||||
|
@ -333,7 +333,7 @@ namespace RageCoop.Client
|
||||
if (p.MainProjectile.AttachedEntity == null)
|
||||
{
|
||||
// Prevent projectiles from exploding next to vehicle
|
||||
if (p.WeaponHash == (WeaponHash)VehicleWeaponHash.Tank || (p.MainProjectile.OwnerEntity?.EntityType==EntityType.Vehicle && p.MainProjectile.Position.DistanceTo(p.Origin) < 2))
|
||||
if (p.WeaponHash == (WeaponHash)VehicleWeaponHash.Tank || (p.MainProjectile.OwnerEntity?.EntityType == EntityType.Vehicle && p.MainProjectile.Position.DistanceTo(p.Origin) < 2))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ namespace RageCoop.Client
|
||||
WeaponUtil.GetFlashFX((WeaponHash)p.WeaponHash),
|
||||
b.Position, b.ForwardVector.ToEulerRotation(v.Bones[35].UpVector), 1);
|
||||
}
|
||||
public static void HandleEvent(PacketType type,NetIncomingMessage msg)
|
||||
public static void HandleEvent(PacketType type, NetIncomingMessage msg)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
|
@ -1,15 +1,13 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using GTA.Math;
|
||||
using GTA.Math;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
internal class BitReader:BinaryReader
|
||||
internal class BitReader : BinaryReader
|
||||
{
|
||||
|
||||
public BitReader(byte[] array):base(new MemoryStream(array))
|
||||
public BitReader(byte[] array) : base(new MemoryStream(array))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -1,20 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GTA.Math;
|
||||
using System.Security.Cryptography;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Sockets;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using GTA.Math;
|
||||
using Lidgren.Network;
|
||||
using Newtonsoft.Json;
|
||||
using System.Runtime.InteropServices;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.NetworkInformation;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
[assembly: InternalsVisibleTo("RageCoop.Server")]
|
||||
[assembly: InternalsVisibleTo("RageCoop.Client")]
|
||||
@ -36,12 +34,12 @@ namespace RageCoop.Core
|
||||
{
|
||||
return ToIgnore.Contains(name);
|
||||
}
|
||||
public static void GetBytesFromObject(object obj,NetOutgoingMessage m)
|
||||
public static void GetBytesFromObject(object obj, NetOutgoingMessage m)
|
||||
{
|
||||
switch (obj)
|
||||
{
|
||||
case byte value:
|
||||
m.Write((byte)0x01);m.Write(value);break;
|
||||
m.Write((byte)0x01); m.Write(value); break;
|
||||
case short value:
|
||||
m.Write((byte)0x02); m.Write(value); break;
|
||||
case ushort value:
|
||||
@ -140,9 +138,8 @@ namespace RageCoop.Core
|
||||
|
||||
private static int getPort(string p)
|
||||
{
|
||||
int port;
|
||||
|
||||
if (!int.TryParse(p, out port)
|
||||
if (!int.TryParse(p, out int port)
|
||||
|| port < IPEndPoint.MinPort
|
||||
|| port > IPEndPoint.MaxPort)
|
||||
{
|
||||
@ -151,7 +148,7 @@ namespace RageCoop.Core
|
||||
|
||||
return port;
|
||||
}
|
||||
public static IPAddress GetLocalAddress(string target= "8.8.8.8")
|
||||
public static IPAddress GetLocalAddress(string target = "8.8.8.8")
|
||||
{
|
||||
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
|
||||
{
|
||||
@ -277,7 +274,7 @@ namespace RageCoop.Core
|
||||
// 16 bytes
|
||||
return new List<byte[]>() { BitConverter.GetBytes(qua.X), BitConverter.GetBytes(qua.Y), BitConverter.GetBytes(qua.Z), BitConverter.GetBytes(qua.W) }.Join(4);
|
||||
}
|
||||
public static T GetPacket<T>(this NetIncomingMessage msg) where T: Packet, new()
|
||||
public static T GetPacket<T>(this NetIncomingMessage msg) where T : Packet, new()
|
||||
{
|
||||
var p = new T();
|
||||
p.Deserialize(msg);
|
||||
@ -285,20 +282,20 @@ namespace RageCoop.Core
|
||||
}
|
||||
public static bool HasPedFlag(this PedDataFlags flagToCheck, PedDataFlags flag)
|
||||
{
|
||||
return (flagToCheck & flag)!=0;
|
||||
return (flagToCheck & flag) != 0;
|
||||
}
|
||||
public static bool HasProjDataFlag(this ProjectileDataFlags flagToCheck, ProjectileDataFlags flag)
|
||||
{
|
||||
return (flagToCheck & flag)!=0;
|
||||
return (flagToCheck & flag) != 0;
|
||||
}
|
||||
|
||||
public static bool HasVehFlag(this VehicleDataFlags flagToCheck, VehicleDataFlags flag)
|
||||
{
|
||||
return (flagToCheck & flag)!=0;
|
||||
return (flagToCheck & flag) != 0;
|
||||
}
|
||||
public static bool HasConfigFlag(this PlayerConfigFlags flagToCheck, PlayerConfigFlags flag)
|
||||
{
|
||||
return (flagToCheck & flag)!=0;
|
||||
return (flagToCheck & flag) != 0;
|
||||
}
|
||||
public static Type GetActualType(this TypeCode code)
|
||||
{
|
||||
@ -365,9 +362,9 @@ namespace RageCoop.Core
|
||||
public static string DumpWithType(this IEnumerable<object> objects)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
foreach(var obj in objects)
|
||||
foreach (var obj in objects)
|
||||
{
|
||||
sb.Append(obj.GetType()+":"+obj.ToString()+"\n");
|
||||
sb.Append(obj.GetType() + ":" + obj.ToString() + "\n");
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
@ -375,9 +372,9 @@ namespace RageCoop.Core
|
||||
{
|
||||
return $"{{{string.Join(",", objects)}}}";
|
||||
}
|
||||
public static void ForEach<T>(this IEnumerable<T> objects,Action<T> action)
|
||||
public static void ForEach<T>(this IEnumerable<T> objects, Action<T> action)
|
||||
{
|
||||
foreach(var obj in objects)
|
||||
foreach (var obj in objects)
|
||||
{
|
||||
action(obj);
|
||||
}
|
||||
@ -399,10 +396,10 @@ namespace RageCoop.Core
|
||||
stream.CopyTo(memoryStream);
|
||||
return memoryStream;
|
||||
}
|
||||
public static byte[] Join(this List<byte[]> arrays,int lengthPerArray=-1)
|
||||
public static byte[] Join(this List<byte[]> arrays, int lengthPerArray = -1)
|
||||
{
|
||||
if (arrays.Count==1) { return arrays[0]; }
|
||||
var output = lengthPerArray== -1 ? new byte[arrays.Sum(arr => arr.Length)] : new byte[arrays.Count*lengthPerArray];
|
||||
if (arrays.Count == 1) { return arrays[0]; }
|
||||
var output = lengthPerArray == -1 ? new byte[arrays.Sum(arr => arr.Length)] : new byte[arrays.Count * lengthPerArray];
|
||||
int writeIdx = 0;
|
||||
foreach (var byteArr in arrays)
|
||||
{
|
||||
|
@ -1,8 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace RageCoop.Core
|
||||
@ -32,26 +31,26 @@ namespace RageCoop.Core
|
||||
private StreamWriter logWriter;
|
||||
|
||||
private string Buffer = "";
|
||||
private Thread LoggerThread;
|
||||
private readonly Thread LoggerThread;
|
||||
private bool Stopping = false;
|
||||
private bool FlushImmediately;
|
||||
private readonly bool FlushImmediately;
|
||||
|
||||
internal Logger(bool flushImmediately = false, bool overwrite = true)
|
||||
{
|
||||
FlushImmediately = flushImmediately;
|
||||
if (File.Exists(LogPath)&&overwrite) { File.Delete(LogPath); }
|
||||
Name=Process.GetCurrentProcess().Id.ToString();
|
||||
if (File.Exists(LogPath) && overwrite) { File.Delete(LogPath); }
|
||||
Name = Process.GetCurrentProcess().Id.ToString();
|
||||
if (!flushImmediately)
|
||||
{
|
||||
LoggerThread=new Thread(() =>
|
||||
LoggerThread = new Thread(() =>
|
||||
{
|
||||
if (!UseConsole)
|
||||
{
|
||||
while (LogPath==default)
|
||||
while (LogPath == default)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
}
|
||||
if (File.Exists(LogPath)&&overwrite) { File.Delete(LogPath); }
|
||||
if (File.Exists(LogPath) && overwrite) { File.Delete(LogPath); }
|
||||
}
|
||||
while (!Stopping)
|
||||
{
|
||||
@ -69,12 +68,12 @@ namespace RageCoop.Core
|
||||
/// <param name="message"></param>
|
||||
public void Info(string message)
|
||||
{
|
||||
if (LogLevel>2) { return; }
|
||||
if (LogLevel > 2) { return; }
|
||||
lock (Buffer)
|
||||
{
|
||||
string msg = string.Format("[{0}][{2}] [INF] {1}", Date(), message, Name);
|
||||
|
||||
Buffer+=msg+"\r\n";
|
||||
Buffer += msg + "\r\n";
|
||||
}
|
||||
if (FlushImmediately)
|
||||
{
|
||||
@ -87,12 +86,12 @@ namespace RageCoop.Core
|
||||
/// <param name="message"></param>
|
||||
public void Warning(string message)
|
||||
{
|
||||
if (LogLevel>3) { return; }
|
||||
if (LogLevel > 3) { return; }
|
||||
lock (Buffer)
|
||||
{
|
||||
string msg = string.Format("[{0}][{2}] [WRN] {1}", Date(), message, Name);
|
||||
|
||||
Buffer+=msg+"\r\n";
|
||||
Buffer += msg + "\r\n";
|
||||
|
||||
}
|
||||
if (FlushImmediately)
|
||||
@ -106,12 +105,12 @@ namespace RageCoop.Core
|
||||
/// <param name="message"></param>
|
||||
public void Error(string message)
|
||||
{
|
||||
if (LogLevel>4) { return; }
|
||||
if (LogLevel > 4) { return; }
|
||||
lock (Buffer)
|
||||
{
|
||||
string msg = string.Format("[{0}][{2}] [ERR] {1}", Date(), message, Name);
|
||||
|
||||
Buffer+=msg+"\r\n";
|
||||
Buffer += msg + "\r\n";
|
||||
}
|
||||
if (FlushImmediately)
|
||||
{
|
||||
@ -125,11 +124,11 @@ namespace RageCoop.Core
|
||||
/// <param name="error"></param>
|
||||
public void Error(string message, Exception error)
|
||||
{
|
||||
if (LogLevel>4) { return; }
|
||||
if (LogLevel > 4) { return; }
|
||||
lock (Buffer)
|
||||
{
|
||||
string msg = string.Format("[{0}][{2}] [ERR] {1}:{3}", Date(), message, Name,error.Message);
|
||||
Buffer+=msg+"\r\n";
|
||||
string msg = string.Format("[{0}][{2}] [ERR] {1}:{3}", Date(), message, Name, error.Message);
|
||||
Buffer += msg + "\r\n";
|
||||
Trace(error.ToString());
|
||||
|
||||
}
|
||||
@ -144,11 +143,11 @@ namespace RageCoop.Core
|
||||
/// <param name="ex"></param>
|
||||
public void Error(Exception ex)
|
||||
{
|
||||
if (LogLevel>4) { return; }
|
||||
if (LogLevel > 4) { return; }
|
||||
lock (Buffer)
|
||||
{
|
||||
string msg = string.Format("[{0}][{2}] [ERR] {1}", Date(), "\r\n"+ex.Message, Name);
|
||||
Buffer+=msg+"\r\n";
|
||||
string msg = string.Format("[{0}][{2}] [ERR] {1}", Date(), "\r\n" + ex.Message, Name);
|
||||
Buffer += msg + "\r\n";
|
||||
Trace(ex.ToString());
|
||||
}
|
||||
if (FlushImmediately)
|
||||
@ -163,12 +162,12 @@ namespace RageCoop.Core
|
||||
public void Debug(string message)
|
||||
{
|
||||
|
||||
if (LogLevel>1) { return; }
|
||||
if (LogLevel > 1) { return; }
|
||||
lock (Buffer)
|
||||
{
|
||||
string msg = string.Format("[{0}][{2}] [DBG] {1}", Date(), message, Name);
|
||||
|
||||
Buffer+=msg+"\r\n";
|
||||
Buffer += msg + "\r\n";
|
||||
}
|
||||
if (FlushImmediately)
|
||||
{
|
||||
@ -181,12 +180,12 @@ namespace RageCoop.Core
|
||||
/// <param name="message"></param>
|
||||
public void Trace(string message)
|
||||
{
|
||||
if (LogLevel>0) { return; }
|
||||
if (LogLevel > 0) { return; }
|
||||
lock (Buffer)
|
||||
{
|
||||
string msg = string.Format("[{0}][{2}] [TRC] {1}", Date(), message, Name);
|
||||
|
||||
Buffer+=msg+"\r\n";
|
||||
Buffer += msg + "\r\n";
|
||||
}
|
||||
if (FlushImmediately)
|
||||
{
|
||||
@ -205,21 +204,21 @@ namespace RageCoop.Core
|
||||
{
|
||||
lock (Buffer)
|
||||
{
|
||||
if (Buffer!="")
|
||||
if (Buffer != "")
|
||||
{
|
||||
if (UseConsole)
|
||||
{
|
||||
Console.Write(Buffer);
|
||||
Buffer="";
|
||||
Buffer = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
logWriter=new StreamWriter(LogPath, true, Encoding.UTF8);
|
||||
logWriter = new StreamWriter(LogPath, true, Encoding.UTF8);
|
||||
logWriter.Write(Buffer);
|
||||
logWriter.Close();
|
||||
Buffer="";
|
||||
Buffer = "";
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
@ -232,7 +231,7 @@ namespace RageCoop.Core
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Stopping=true;
|
||||
Stopping = true;
|
||||
LoggerThread?.Join();
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using GTA.Math;
|
||||
using GTA.Math;
|
||||
using System;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
internal static class MathExtensions
|
||||
{
|
||||
public const float Deg2Rad=(float)(Math.PI* 2) / 360;
|
||||
public const float Deg2Rad = (float)(Math.PI * 2) / 360;
|
||||
public const float Rad2Deg = 360 / (float)(Math.PI * 2);
|
||||
|
||||
public static Vector3 ToDirection(this Vector3 rotation)
|
||||
@ -81,14 +81,14 @@ namespace RageCoop.Core
|
||||
vect = vect.ToRadians();
|
||||
|
||||
float rollOver2 = vect.Z * 0.5f;
|
||||
float sinRollOver2 = (float)Math.Sin((double)rollOver2);
|
||||
float cosRollOver2 = (float)Math.Cos((double)rollOver2);
|
||||
float sinRollOver2 = (float)Math.Sin(rollOver2);
|
||||
float cosRollOver2 = (float)Math.Cos(rollOver2);
|
||||
float pitchOver2 = vect.Y * 0.5f;
|
||||
float sinPitchOver2 = (float)Math.Sin((double)pitchOver2);
|
||||
float cosPitchOver2 = (float)Math.Cos((double)pitchOver2);
|
||||
float sinPitchOver2 = (float)Math.Sin(pitchOver2);
|
||||
float cosPitchOver2 = (float)Math.Cos(pitchOver2);
|
||||
float yawOver2 = vect.X * 0.5f; // pitch
|
||||
float sinYawOver2 = (float)Math.Sin((double)yawOver2);
|
||||
float cosYawOver2 = (float)Math.Cos((double)yawOver2);
|
||||
float sinYawOver2 = (float)Math.Sin(yawOver2);
|
||||
float cosYawOver2 = (float)Math.Cos(yawOver2);
|
||||
Quaternion result = new Quaternion()
|
||||
{
|
||||
X = cosYawOver2 * cosPitchOver2 * cosRollOver2 + sinYawOver2 * sinPitchOver2 * sinRollOver2,
|
||||
@ -110,7 +110,7 @@ namespace RageCoop.Core
|
||||
}
|
||||
public static Vector3 ToDegree(this Vector3 radian)
|
||||
{
|
||||
return radian*(float)(180/Math.PI);
|
||||
return radian * (float)(180 / Math.PI);
|
||||
}
|
||||
public static Vector3 ToEulerDegrees(this Quaternion q)
|
||||
{
|
||||
@ -158,7 +158,7 @@ namespace RageCoop.Core
|
||||
}
|
||||
public static float GetCosTheta(this Vector3 v1, Vector3 v2)
|
||||
{
|
||||
return Vector3.Dot(v1, v2)/(v1.Length()*v2.Length());
|
||||
return Vector3.Dot(v1, v2) / (v1.Length() * v2.Length());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using Lidgren.Network;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Lidgren.Network;
|
||||
using System.Threading;
|
||||
|
||||
namespace RageCoop.Core
|
||||
@ -10,19 +9,19 @@ namespace RageCoop.Core
|
||||
{
|
||||
public EventHandler<NetIncomingMessage> OnMessageReceived;
|
||||
private readonly Thread ListenerThread;
|
||||
private bool _stopping=false;
|
||||
public CoopPeer(NetPeerConfiguration config):base(config)
|
||||
private bool _stopping = false;
|
||||
public CoopPeer(NetPeerConfiguration config) : base(config)
|
||||
{
|
||||
Start();
|
||||
NetIncomingMessage msg;
|
||||
ListenerThread=new Thread(() =>
|
||||
ListenerThread = new Thread(() =>
|
||||
{
|
||||
while (!_stopping)
|
||||
{
|
||||
msg=WaitMessage(200);
|
||||
if (msg!=null)
|
||||
msg = WaitMessage(200);
|
||||
if (msg != null)
|
||||
{
|
||||
OnMessageReceived?.Invoke(this,msg);
|
||||
OnMessageReceived?.Invoke(this, msg);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -34,7 +33,7 @@ namespace RageCoop.Core
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
_stopping=true;
|
||||
_stopping = true;
|
||||
Shutdown("Bye!");
|
||||
ListenerThread.Join();
|
||||
}
|
||||
@ -51,7 +50,7 @@ namespace RageCoop.Core
|
||||
p.Pack(outgoingMessage);
|
||||
SendMessage(outgoingMessage, connections, method, (int)channel);
|
||||
}
|
||||
public void Send(Packet p,IList<NetConnection> cons, ConnectionChannel channel = ConnectionChannel.Default, NetDeliveryMethod method = NetDeliveryMethod.UnreliableSequenced)
|
||||
public void Send(Packet p, IList<NetConnection> cons, ConnectionChannel channel = ConnectionChannel.Default, NetDeliveryMethod method = NetDeliveryMethod.UnreliableSequenced)
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage = CreateMessage();
|
||||
p.Pack(outgoingMessage);
|
||||
|
@ -1,18 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
internal static class HttpHelper
|
||||
{
|
||||
public static void DownloadFile(string url,string destination,Action<int> progressCallback)
|
||||
public static void DownloadFile(string url, string destination, Action<int> progressCallback)
|
||||
{
|
||||
if (File.Exists(destination)) { File.Delete(destination); }
|
||||
AutoResetEvent ae=new AutoResetEvent(false);
|
||||
AutoResetEvent ae = new AutoResetEvent(false);
|
||||
WebClient client = new WebClient();
|
||||
|
||||
// TLS only
|
||||
|
@ -1,19 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Lidgren.Network;
|
||||
using System.Threading;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
internal class PublicKey{
|
||||
public PublicKey(){
|
||||
internal class PublicKey
|
||||
{
|
||||
public PublicKey()
|
||||
{
|
||||
|
||||
}
|
||||
public static PublicKey FromServerInfo(ServerInfo info){
|
||||
return new PublicKey{
|
||||
Modulus=Convert.FromBase64String(info.publicKeyModulus),
|
||||
Exponent=Convert.FromBase64String(info.publicKeyExponent)
|
||||
public static PublicKey FromServerInfo(ServerInfo info)
|
||||
{
|
||||
return new PublicKey
|
||||
{
|
||||
Modulus = Convert.FromBase64String(info.publicKeyModulus),
|
||||
Exponent = Convert.FromBase64String(info.publicKeyExponent)
|
||||
};
|
||||
}
|
||||
public byte[] Modulus;
|
||||
|
@ -1,9 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace RageCoop.Core
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A json object representing a server's information as annouced to master server.
|
||||
@ -30,8 +25,8 @@ namespace RageCoop.Core
|
||||
public string ztID { get; set; }
|
||||
|
||||
public string ztAddress { get; set; }
|
||||
public string publicKeyModulus{get;set;}
|
||||
public string publicKeyExponent{get;set;}
|
||||
public string publicKeyModulus { get; set; }
|
||||
public string publicKeyExponent { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using Newtonsoft.Json;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace RageCoop.Core
|
||||
@ -15,13 +13,13 @@ namespace RageCoop.Core
|
||||
public ZeroTierNetwork(string line)
|
||||
{
|
||||
// <nwid> <name> <mac> <status> <type> <dev> <ZT assigned ips>
|
||||
var v = Regex.Split(line," ").Skip(2).ToArray();
|
||||
ID=v[0];
|
||||
Name=v[1];
|
||||
Mac=v[2];
|
||||
Status=v[3];
|
||||
Type=v[4];
|
||||
Device=v[5];
|
||||
var v = Regex.Split(line, " ").Skip(2).ToArray();
|
||||
ID = v[0];
|
||||
Name = v[1];
|
||||
Mac = v[2];
|
||||
Status = v[3];
|
||||
Type = v[4];
|
||||
Device = v[5];
|
||||
foreach (var i in v[6].Split(','))
|
||||
{
|
||||
Addresses.Add(i.Split('/')[0]);
|
||||
@ -33,43 +31,43 @@ namespace RageCoop.Core
|
||||
public string Status;
|
||||
public string Type;
|
||||
public string Device;
|
||||
public List<string> Addresses=new List<string>();
|
||||
public List<string> Addresses = new List<string>();
|
||||
|
||||
}
|
||||
internal static class ZeroTierHelper
|
||||
{
|
||||
private static readonly string _path="zerotier-cli";
|
||||
private static readonly string _path = "zerotier-cli";
|
||||
private static readonly string _arg = "";
|
||||
static ZeroTierHelper()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
var batpath= Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "ZeroTier", "One", "zerotier-cli.bat");
|
||||
_arg=$"/c \"{batpath}\" ";
|
||||
_path="cmd.exe";
|
||||
var batpath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "ZeroTier", "One", "zerotier-cli.bat");
|
||||
_arg = $"/c \"{batpath}\" ";
|
||||
_path = "cmd.exe";
|
||||
}
|
||||
var status = RunCommand("status");
|
||||
if (!status.StartsWith("200"))
|
||||
{
|
||||
throw new Exception("ZeroTier not ready: "+status);
|
||||
throw new Exception("ZeroTier not ready: " + status);
|
||||
}
|
||||
}
|
||||
public static ZeroTierNetwork Join(string networkId, int timeout=10000)
|
||||
public static ZeroTierNetwork Join(string networkId, int timeout = 10000)
|
||||
{
|
||||
var p = Run("join "+networkId);
|
||||
var p = Run("join " + networkId);
|
||||
var o = p.StandardOutput.ReadToEnd();
|
||||
if (!o.StartsWith("200 join OK"))
|
||||
{
|
||||
throw new Exception(o+p.StandardError.ReadToEnd());
|
||||
throw new Exception(o + p.StandardError.ReadToEnd());
|
||||
}
|
||||
if (timeout==0) { return Networks[networkId]; }
|
||||
if (timeout == 0) { return Networks[networkId]; }
|
||||
int i = 0;
|
||||
while (i<=timeout)
|
||||
while (i <= timeout)
|
||||
{
|
||||
i+=100;
|
||||
if(Networks.TryGetValue(networkId,out var n))
|
||||
i += 100;
|
||||
if (Networks.TryGetValue(networkId, out var n))
|
||||
{
|
||||
if (n.Addresses.Count!=0 && (!n.Addresses.Where(x=>x=="-").Any()))
|
||||
if (n.Addresses.Count != 0 && (!n.Addresses.Where(x => x == "-").Any()))
|
||||
{
|
||||
return n;
|
||||
}
|
||||
@ -84,16 +82,17 @@ namespace RageCoop.Core
|
||||
}
|
||||
public static void Leave(string networkId)
|
||||
{
|
||||
var p = Run("leave "+networkId);
|
||||
var p = Run("leave " + networkId);
|
||||
var o = p.StandardOutput.ReadToEnd();
|
||||
if (!o.StartsWith("200 leave OK"))
|
||||
{
|
||||
throw new Exception(o+p.StandardError.ReadToEnd());
|
||||
throw new Exception(o + p.StandardError.ReadToEnd());
|
||||
}
|
||||
}
|
||||
public static Dictionary<string, ZeroTierNetwork> Networks
|
||||
{
|
||||
get {
|
||||
get
|
||||
{
|
||||
Dictionary<string, ZeroTierNetwork> networks = new Dictionary<string, ZeroTierNetwork>();
|
||||
var p = Run("listnetworks");
|
||||
var lines = Regex.Split(p.StandardOutput.ReadToEnd(), "\n").Skip(1);
|
||||
@ -113,14 +112,14 @@ namespace RageCoop.Core
|
||||
private static Process Run(string args)
|
||||
{
|
||||
var p = new Process();
|
||||
p.StartInfo=new ProcessStartInfo()
|
||||
p.StartInfo = new ProcessStartInfo()
|
||||
{
|
||||
FileName = _path,
|
||||
Arguments =_arg+args,
|
||||
Arguments = _arg + args,
|
||||
UseShellExecute = false,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
CreateNoWindow=true,
|
||||
CreateNoWindow = true,
|
||||
};
|
||||
p.Start();
|
||||
p.WaitForExit();
|
||||
@ -129,7 +128,7 @@ namespace RageCoop.Core
|
||||
private static string RunCommand(string command)
|
||||
{
|
||||
var p = Run(command);
|
||||
return p.StandardOutput.ReadToEnd()+p.StandardError.ReadToEnd();
|
||||
return p.StandardOutput.ReadToEnd() + p.StandardError.ReadToEnd();
|
||||
}
|
||||
public static void Check()
|
||||
{
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using GTA.Math;
|
||||
using Lidgren.Network;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using GTA.Math;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
@ -43,7 +43,7 @@ namespace RageCoop.Core
|
||||
#endregion
|
||||
|
||||
#region MESSAGE-WRITE
|
||||
public static void Write(this NetOutgoingMessage m,Vector3 v)
|
||||
public static void Write(this NetOutgoingMessage m, Vector3 v)
|
||||
{
|
||||
m.Write(v.X);
|
||||
m.Write(v.Y);
|
||||
@ -120,7 +120,7 @@ namespace RageCoop.Core
|
||||
bytes.AddInt(toadd.Length);
|
||||
bytes.AddRange(toadd);
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
internal static bool IsSyncEvent(this PacketType p)
|
||||
{
|
||||
|
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Lidgren.Network;
|
||||
using Lidgren.Network;
|
||||
using System;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
@ -11,8 +10,8 @@ namespace RageCoop.Core
|
||||
internal class ChatMessage : Packet
|
||||
{
|
||||
public override PacketType Type => PacketType.ChatMessage;
|
||||
private Func<string, byte[]> crypt;
|
||||
private Func<byte[], byte[]> decrypt;
|
||||
private readonly Func<string, byte[]> crypt;
|
||||
private readonly Func<byte[], byte[]> decrypt;
|
||||
public ChatMessage(Func<string, byte[]> crypter)
|
||||
{
|
||||
crypt = crypter;
|
||||
|
@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Lidgren.Network;
|
||||
using Lidgren.Network;
|
||||
using System;
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
internal partial class Packets
|
||||
@ -10,25 +8,25 @@ namespace RageCoop.Core
|
||||
internal class CustomEvent : Packet
|
||||
{
|
||||
public override PacketType Type => (_queued ? PacketType.CustomEventQueued : PacketType.CustomEvent);
|
||||
public CustomEvent(Func<byte,NetIncomingMessage,object> onResolve = null,bool queued=false)
|
||||
public CustomEvent(Func<byte, NetIncomingMessage, object> onResolve = null, bool queued = false)
|
||||
{
|
||||
_resolve= onResolve;
|
||||
_queued= queued;
|
||||
_resolve = onResolve;
|
||||
_queued = queued;
|
||||
}
|
||||
private bool _queued;
|
||||
private readonly bool _queued;
|
||||
private Func<byte, NetIncomingMessage, object> _resolve { get; set; }
|
||||
public int Hash { get; set; }
|
||||
public object[] Args { get; set; }
|
||||
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
Args= Args ?? new object[] { };
|
||||
Args = Args ?? new object[] { };
|
||||
|
||||
m.Write(Hash);
|
||||
m.Write(Args.Length);
|
||||
foreach (var arg in Args)
|
||||
{
|
||||
CoreUtils.GetBytesFromObject(arg,m);
|
||||
CoreUtils.GetBytesFromObject(arg, m);
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,51 +35,51 @@ namespace RageCoop.Core
|
||||
|
||||
|
||||
Hash = m.ReadInt32();
|
||||
var len=m.ReadInt32();
|
||||
Args=new object[len];
|
||||
var len = m.ReadInt32();
|
||||
Args = new object[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
byte type = m.ReadByte();
|
||||
switch (type)
|
||||
{
|
||||
case 0x01:
|
||||
Args[i]=m.ReadByte(); break;
|
||||
Args[i] = m.ReadByte(); break;
|
||||
case 0x02:
|
||||
Args[i]=m.ReadInt32(); break;
|
||||
Args[i] = m.ReadInt32(); break;
|
||||
case 0x03:
|
||||
Args[i]=m.ReadUInt16(); break;
|
||||
Args[i] = m.ReadUInt16(); break;
|
||||
case 0x04:
|
||||
Args[i]=m.ReadInt32(); break;
|
||||
Args[i] = m.ReadInt32(); break;
|
||||
case 0x05:
|
||||
Args[i]=m.ReadUInt32(); break;
|
||||
Args[i] = m.ReadUInt32(); break;
|
||||
case 0x06:
|
||||
Args[i]=m.ReadInt64(); break;
|
||||
Args[i] = m.ReadInt64(); break;
|
||||
case 0x07:
|
||||
Args[i]=m.ReadUInt64(); break;
|
||||
Args[i] = m.ReadUInt64(); break;
|
||||
case 0x08:
|
||||
Args[i]=m.ReadFloat(); break;
|
||||
Args[i] = m.ReadFloat(); break;
|
||||
case 0x09:
|
||||
Args[i]=m.ReadBoolean(); break;
|
||||
Args[i] = m.ReadBoolean(); break;
|
||||
case 0x10:
|
||||
Args[i]=m.ReadString(); break;
|
||||
Args[i] = m.ReadString(); break;
|
||||
case 0x11:
|
||||
Args[i]=m.ReadVector3(); break;
|
||||
Args[i] = m.ReadVector3(); break;
|
||||
case 0x12:
|
||||
Args[i]=m.ReadQuaternion(); break;
|
||||
Args[i] = m.ReadQuaternion(); break;
|
||||
case 0x13:
|
||||
Args[i]=(GTA.Model)m.ReadInt32(); break;
|
||||
Args[i] = (GTA.Model)m.ReadInt32(); break;
|
||||
case 0x14:
|
||||
Args[i]=m.ReadVector2(); break;
|
||||
Args[i] = m.ReadVector2(); break;
|
||||
case 0x15:
|
||||
Args[i] = m.ReadByteArray(); break;
|
||||
default:
|
||||
if (_resolve==null)
|
||||
if (_resolve == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Unexpected type: {type}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Args[i]=_resolve(type, m); break;
|
||||
Args[i] = _resolve(type, m); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
internal enum FileResponse:byte
|
||||
internal enum FileResponse : byte
|
||||
{
|
||||
NeedToDownload=0,
|
||||
AlreadyExists=1,
|
||||
Completed=2,
|
||||
Loaded=3,
|
||||
LoadFailed=4,
|
||||
NeedToDownload = 0,
|
||||
AlreadyExists = 1,
|
||||
Completed = 2,
|
||||
Loaded = 3,
|
||||
LoadFailed = 4,
|
||||
}
|
||||
internal partial class Packets
|
||||
{
|
||||
|
@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Lidgren.Network;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
@ -33,7 +31,7 @@ namespace RageCoop.Core
|
||||
TargetID = m.ReadInt32();
|
||||
TargetInternal = m.ReadString();
|
||||
TargetExternal = m.ReadString();
|
||||
Connect=m.ReadBoolean();
|
||||
Connect = m.ReadBoolean();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -45,7 +43,7 @@ namespace RageCoop.Core
|
||||
/// <summary>
|
||||
/// 1:initial, 2:acknowledged, 3:confirmed
|
||||
/// </summary>
|
||||
public byte Status { get;set;}
|
||||
public byte Status { get; set; }
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using Lidgren.Network;
|
||||
using System.Collections.Generic;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
@ -15,7 +14,7 @@ namespace RageCoop.Core
|
||||
public override PacketType Type => PacketType.ConnectionRequest;
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
var data=new List<byte>(10);
|
||||
var data = new List<byte>(10);
|
||||
m.Write(TargetID);
|
||||
}
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
|
@ -1,59 +1,55 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Lidgren.Network;
|
||||
using Newtonsoft.Json;
|
||||
using GTA.Math;
|
||||
using Lidgren.Network;
|
||||
using System;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
internal enum PacketType:byte
|
||||
internal enum PacketType : byte
|
||||
{
|
||||
Handshake=0,
|
||||
PlayerConnect=1,
|
||||
PlayerDisconnect=2,
|
||||
PlayerInfoUpdate=3,
|
||||
PublicKeyRequest=4,
|
||||
PublicKeyResponse=5,
|
||||
Request=6,
|
||||
Response=7,
|
||||
Handshake = 0,
|
||||
PlayerConnect = 1,
|
||||
PlayerDisconnect = 2,
|
||||
PlayerInfoUpdate = 3,
|
||||
PublicKeyRequest = 4,
|
||||
PublicKeyResponse = 5,
|
||||
Request = 6,
|
||||
Response = 7,
|
||||
PingPong = 8,
|
||||
HandshakeSuccess = 9,
|
||||
ChatMessage =10,
|
||||
ChatMessage = 10,
|
||||
|
||||
FileTransferChunk=11,
|
||||
FileTransferRequest=12,
|
||||
FileTransferChunk = 11,
|
||||
FileTransferRequest = 12,
|
||||
FileTransferResponse = 13,
|
||||
FileTransferComplete =14,
|
||||
AllResourcesSent=15,
|
||||
FileTransferComplete = 14,
|
||||
AllResourcesSent = 15,
|
||||
|
||||
CustomEvent = 16,
|
||||
CustomEventQueued = 17,
|
||||
|
||||
ConnectionRequest=18,
|
||||
ConnectionRequest = 18,
|
||||
P2PConnect = 19,
|
||||
HolePunchInit=20,
|
||||
HolePunch=21,
|
||||
HolePunchInit = 20,
|
||||
HolePunch = 21,
|
||||
|
||||
Voice = 22,
|
||||
|
||||
#region Sync
|
||||
PedSync = 23,
|
||||
VehicleSync = 24,
|
||||
ProjectileSync =25,
|
||||
ProjectileSync = 25,
|
||||
#endregion
|
||||
|
||||
#region EVENT
|
||||
|
||||
PedKilled=30,
|
||||
BulletShot=31,
|
||||
PedKilled = 30,
|
||||
BulletShot = 31,
|
||||
VehicleBulletShot = 32,
|
||||
OwnerChanged =35,
|
||||
NozzleTransform=37,
|
||||
OwnerChanged = 35,
|
||||
NozzleTransform = 37,
|
||||
|
||||
#endregion
|
||||
|
||||
Unknown=255
|
||||
Unknown = 255
|
||||
}
|
||||
internal enum ConnectionChannel
|
||||
{
|
||||
@ -64,18 +60,18 @@ namespace RageCoop.Core
|
||||
Mod = 4,
|
||||
File = 5,
|
||||
Event = 6,
|
||||
RequestResponse=7,
|
||||
RequestResponse = 7,
|
||||
PingPong = 8,
|
||||
VehicleSync = 9,
|
||||
PedSync= 10,
|
||||
PedSync = 10,
|
||||
ProjectileSync = 11,
|
||||
SyncEvents = 12,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
internal enum PedDataFlags:ushort
|
||||
internal enum PedDataFlags : ushort
|
||||
{
|
||||
None=0,
|
||||
None = 0,
|
||||
IsAiming = 1 << 0,
|
||||
IsInStealthMode = 1 << 1,
|
||||
IsReloading = 1 << 2,
|
||||
@ -91,10 +87,10 @@ namespace RageCoop.Core
|
||||
IsInCoverFacingLeft = 1 << 12,
|
||||
IsBlindFiring = 1 << 13,
|
||||
IsInvincible = 1 << 14,
|
||||
IsFullSync = 1<<15 ,
|
||||
IsFullSync = 1 << 15,
|
||||
}
|
||||
|
||||
internal enum ProjectileDataFlags:byte
|
||||
internal enum ProjectileDataFlags : byte
|
||||
{
|
||||
None = 0,
|
||||
Exploded = 1 << 0,
|
||||
@ -103,9 +99,9 @@ namespace RageCoop.Core
|
||||
IsShotByVehicle = 1 << 3,
|
||||
}
|
||||
#region ===== VEHICLE DATA =====
|
||||
internal enum VehicleDataFlags:ushort
|
||||
internal enum VehicleDataFlags : ushort
|
||||
{
|
||||
None=0,
|
||||
None = 0,
|
||||
IsEngineRunning = 1 << 0,
|
||||
AreLightsOn = 1 << 1,
|
||||
AreBrakeLightsOn = 1 << 2,
|
||||
@ -117,18 +113,18 @@ namespace RageCoop.Core
|
||||
IsParachuteActive = 1 << 8,
|
||||
IsRocketBoostActive = 1 << 9,
|
||||
IsAircraft = 1 << 10,
|
||||
IsDeluxoHovering=1 << 11,
|
||||
HasRoof=1 << 12,
|
||||
IsFullSync = 1<<13,
|
||||
IsOnFire = 1<<14,
|
||||
Repaired = 1<<15,
|
||||
IsDeluxoHovering = 1 << 11,
|
||||
HasRoof = 1 << 12,
|
||||
IsFullSync = 1 << 13,
|
||||
IsOnFire = 1 << 14,
|
||||
Repaired = 1 << 15,
|
||||
}
|
||||
|
||||
internal enum PlayerConfigFlags : byte
|
||||
{
|
||||
None = 0,
|
||||
ShowBlip= 1 << 0,
|
||||
ShowNameTag= 1 << 1
|
||||
ShowBlip = 1 << 0,
|
||||
ShowNameTag = 1 << 1
|
||||
}
|
||||
|
||||
internal struct VehicleDamageModel
|
||||
|
@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using GTA;
|
||||
using GTA.Math;
|
||||
using GTA;
|
||||
using Lidgren.Network;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
@ -59,7 +57,7 @@ namespace RageCoop.Core
|
||||
|
||||
public BlipSprite BlipSprite { get; set; } = 0;
|
||||
public float BlipScale { get; set; } = 1;
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
@ -79,10 +77,10 @@ namespace RageCoop.Core
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Speed>=4)
|
||||
if (Speed >= 4)
|
||||
{
|
||||
m.Write(VehicleID);
|
||||
m.Write((byte)(Seat+3));
|
||||
m.Write((byte)(Seat + 3));
|
||||
}
|
||||
m.Write(Position);
|
||||
}
|
||||
@ -121,7 +119,7 @@ namespace RageCoop.Core
|
||||
m.Write(WeaponTint);
|
||||
|
||||
m.Write((byte)BlipColor);
|
||||
if ((byte)BlipColor!=255)
|
||||
if ((byte)BlipColor != 255)
|
||||
{
|
||||
m.Write((ushort)BlipSprite);
|
||||
m.Write(BlipScale);
|
||||
@ -137,25 +135,25 @@ namespace RageCoop.Core
|
||||
|
||||
|
||||
ID = m.ReadInt32();
|
||||
OwnerID=m.ReadInt32();
|
||||
OwnerID = m.ReadInt32();
|
||||
Flags = (PedDataFlags)m.ReadUInt16();
|
||||
Health = m.ReadInt32();
|
||||
Speed = m.ReadByte();
|
||||
|
||||
if (Flags.HasPedFlag(PedDataFlags.IsRagdoll))
|
||||
{
|
||||
HeadPosition=m.ReadVector3();
|
||||
RightFootPosition=m.ReadVector3();
|
||||
LeftFootPosition=m.ReadVector3();
|
||||
Position=HeadPosition;
|
||||
HeadPosition = m.ReadVector3();
|
||||
RightFootPosition = m.ReadVector3();
|
||||
LeftFootPosition = m.ReadVector3();
|
||||
Position = HeadPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Vehicle related
|
||||
if (Speed>=4)
|
||||
if (Speed >= 4)
|
||||
{
|
||||
VehicleID=m.ReadInt32();
|
||||
Seat=(VehicleSeat)(m.ReadByte()-3);
|
||||
VehicleID = m.ReadInt32();
|
||||
Seat = (VehicleSeat)(m.ReadByte() - 3);
|
||||
}
|
||||
|
||||
// Read player position
|
||||
@ -171,7 +169,7 @@ namespace RageCoop.Core
|
||||
AimCoords = m.ReadVector3();
|
||||
}
|
||||
|
||||
Heading=m.ReadFloat();
|
||||
Heading = m.ReadFloat();
|
||||
|
||||
if (Flags.HasPedFlag(PedDataFlags.IsFullSync))
|
||||
{
|
||||
@ -182,7 +180,7 @@ namespace RageCoop.Core
|
||||
CurrentWeaponHash = m.ReadUInt32();
|
||||
|
||||
// Read player clothes
|
||||
Clothes =m.ReadBytes(36);
|
||||
Clothes = m.ReadBytes(36);
|
||||
|
||||
// Read player weapon components
|
||||
if (m.ReadBoolean())
|
||||
@ -194,14 +192,14 @@ namespace RageCoop.Core
|
||||
WeaponComponents.Add(m.ReadUInt32(), m.ReadBoolean());
|
||||
}
|
||||
}
|
||||
WeaponTint=m.ReadByte();
|
||||
WeaponTint = m.ReadByte();
|
||||
|
||||
BlipColor=(BlipColor)m.ReadByte();
|
||||
BlipColor = (BlipColor)m.ReadByte();
|
||||
|
||||
if ((byte)BlipColor!=255)
|
||||
if ((byte)BlipColor != 255)
|
||||
{
|
||||
BlipSprite=(BlipSprite)m.ReadUInt16();
|
||||
BlipScale=m.ReadFloat();
|
||||
BlipSprite = (BlipSprite)m.ReadUInt16();
|
||||
BlipScale = m.ReadFloat();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
@ -1,9 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using GTA.Math;
|
||||
using System.Net;
|
||||
using GTA.Math;
|
||||
using Lidgren.Network;
|
||||
using System.Net;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
@ -80,14 +77,14 @@ namespace RageCoop.Core
|
||||
// Read ModVersion
|
||||
ModVersion = m.ReadString();
|
||||
|
||||
InternalEndPoint=CoreUtils.StringToEndPoint(m.ReadString());
|
||||
InternalEndPoint = CoreUtils.StringToEndPoint(m.ReadString());
|
||||
|
||||
AesKeyCrypted=m.ReadByteArray();
|
||||
AesKeyCrypted = m.ReadByteArray();
|
||||
|
||||
AesIVCrypted=m.ReadByteArray();
|
||||
AesIVCrypted = m.ReadByteArray();
|
||||
|
||||
|
||||
PasswordEncrypted=m.ReadByteArray();
|
||||
PasswordEncrypted = m.ReadByteArray();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -98,7 +95,7 @@ namespace RageCoop.Core
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
m.Write(Players.Length);
|
||||
foreach(var p in Players)
|
||||
foreach (var p in Players)
|
||||
{
|
||||
m.Write(p.ID);
|
||||
m.Write(p.Username);
|
||||
@ -107,13 +104,13 @@ namespace RageCoop.Core
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
|
||||
Players=new PlayerData[m.ReadInt32()];
|
||||
for(int i = 0; i<Players.Length; i++)
|
||||
Players = new PlayerData[m.ReadInt32()];
|
||||
for (int i = 0; i < Players.Length; i++)
|
||||
{
|
||||
Players[i]=new PlayerData()
|
||||
Players[i] = new PlayerData()
|
||||
{
|
||||
ID=m.ReadInt32(),
|
||||
Username=m.ReadString(),
|
||||
ID = m.ReadInt32(),
|
||||
Username = m.ReadString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -206,11 +203,11 @@ namespace RageCoop.Core
|
||||
// Read Username
|
||||
Username = m.ReadString();
|
||||
|
||||
Latency=m.ReadFloat();
|
||||
Latency = m.ReadFloat();
|
||||
|
||||
Position=m.ReadVector3();
|
||||
Position = m.ReadVector3();
|
||||
|
||||
IsHost=m.ReadBoolean();
|
||||
IsHost = m.ReadBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,8 +234,8 @@ namespace RageCoop.Core
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
|
||||
Modulus=m.ReadByteArray();
|
||||
Exponent=m.ReadByteArray();
|
||||
Modulus = m.ReadByteArray();
|
||||
Exponent = m.ReadByteArray();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using GTA.Math;
|
||||
using GTA.Math;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
@ -63,9 +60,9 @@ namespace RageCoop.Core
|
||||
ID = m.ReadInt32();
|
||||
|
||||
// Read ShooterID
|
||||
ShooterID= m.ReadInt32();
|
||||
ShooterID = m.ReadInt32();
|
||||
|
||||
WeaponHash= m.ReadUInt32();
|
||||
WeaponHash = m.ReadUInt32();
|
||||
|
||||
// Read position
|
||||
Position = m.ReadVector3();
|
||||
@ -74,9 +71,9 @@ namespace RageCoop.Core
|
||||
Rotation = m.ReadVector3();
|
||||
|
||||
// Read velocity
|
||||
Velocity =m.ReadVector3();
|
||||
Velocity = m.ReadVector3();
|
||||
|
||||
Flags=(ProjectileDataFlags)m.ReadByte();
|
||||
Flags = (ProjectileDataFlags)m.ReadByte();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using GTA.Math;
|
||||
using GTA.Math;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
@ -47,16 +44,16 @@ namespace RageCoop.Core
|
||||
|
||||
|
||||
// Read OwnerID
|
||||
OwnerID=m.ReadInt32();
|
||||
OwnerID = m.ReadInt32();
|
||||
|
||||
// Read WeponHash
|
||||
WeaponHash=m.ReadUInt32();
|
||||
WeaponHash = m.ReadUInt32();
|
||||
|
||||
// Read StartPosition
|
||||
StartPosition=m.ReadVector3();
|
||||
StartPosition = m.ReadVector3();
|
||||
|
||||
// Read EndPosition
|
||||
EndPosition=m.ReadVector3();
|
||||
EndPosition = m.ReadVector3();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
@ -31,8 +28,8 @@ namespace RageCoop.Core
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
|
||||
VehicleID=m.ReadInt32();
|
||||
Hover=m.ReadBoolean();
|
||||
VehicleID = m.ReadInt32();
|
||||
Hover = m.ReadBoolean();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
@ -27,8 +24,8 @@ namespace RageCoop.Core
|
||||
#region NetIncomingMessageToPacket
|
||||
|
||||
|
||||
ID=m.ReadInt32();
|
||||
NewOwnerID=m.ReadInt32();
|
||||
ID = m.ReadInt32();
|
||||
NewOwnerID = m.ReadInt32();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
@ -29,7 +26,7 @@ namespace RageCoop.Core
|
||||
#region NetIncomingMessageToPacket
|
||||
|
||||
|
||||
VictimID=m.ReadInt32();
|
||||
VictimID = m.ReadInt32();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using GTA.Math;
|
||||
using GTA.Math;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
@ -39,11 +36,11 @@ namespace RageCoop.Core
|
||||
#region NetIncomingMessageToPacket
|
||||
|
||||
|
||||
OwnerID=m.ReadInt32();
|
||||
Bone=m.ReadUInt16();
|
||||
WeaponHash=m.ReadUInt32();
|
||||
StartPosition=m.ReadVector3();
|
||||
EndPosition=m.ReadVector3();
|
||||
OwnerID = m.ReadInt32();
|
||||
Bone = m.ReadUInt16();
|
||||
WeaponHash = m.ReadUInt32();
|
||||
StartPosition = m.ReadVector3();
|
||||
EndPosition = m.ReadVector3();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using GTA;
|
||||
using GTA;
|
||||
using GTA.Math;
|
||||
using Lidgren.Network;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
@ -136,7 +133,7 @@ namespace RageCoop.Core
|
||||
// Write LicensePlate
|
||||
m.Write(LicensePlate);
|
||||
|
||||
m.Write((byte)(Livery+1));
|
||||
m.Write((byte)(Livery + 1));
|
||||
}
|
||||
}
|
||||
|
||||
@ -146,13 +143,13 @@ namespace RageCoop.Core
|
||||
|
||||
ID = m.ReadInt32();
|
||||
OwnerID = m.ReadInt32();
|
||||
Flags=(VehicleDataFlags)m.ReadUInt16();
|
||||
Flags = (VehicleDataFlags)m.ReadUInt16();
|
||||
Position = m.ReadVector3();
|
||||
Quaternion=m.ReadQuaternion();
|
||||
Velocity =m.ReadVector3();
|
||||
RotationVelocity=m.ReadVector3();
|
||||
ThrottlePower=m.ReadFloat();
|
||||
BrakePower=m.ReadFloat();
|
||||
Quaternion = m.ReadQuaternion();
|
||||
Velocity = m.ReadVector3();
|
||||
RotationVelocity = m.ReadVector3();
|
||||
ThrottlePower = m.ReadFloat();
|
||||
BrakePower = m.ReadFloat();
|
||||
SteeringAngle = m.ReadFloat();
|
||||
|
||||
|
||||
@ -178,7 +175,7 @@ namespace RageCoop.Core
|
||||
}
|
||||
if (Flags.HasVehFlag(VehicleDataFlags.HasRoof))
|
||||
{
|
||||
RoofState=m.ReadByte();
|
||||
RoofState = m.ReadByte();
|
||||
}
|
||||
|
||||
// Read vehicle colors
|
||||
@ -204,7 +201,7 @@ namespace RageCoop.Core
|
||||
DamageModel = new VehicleDamageModel()
|
||||
{
|
||||
BrokenDoors = m.ReadByte(),
|
||||
OpenedDoors=m.ReadByte(),
|
||||
OpenedDoors = m.ReadByte(),
|
||||
BrokenWindows = m.ReadByte(),
|
||||
BurstedTires = m.ReadInt16(),
|
||||
LeftHeadLightBroken = m.ReadByte(),
|
||||
@ -214,14 +211,14 @@ namespace RageCoop.Core
|
||||
|
||||
|
||||
// Read LockStatus
|
||||
LockStatus=(VehicleLockStatus)m.ReadByte();
|
||||
LockStatus = (VehicleLockStatus)m.ReadByte();
|
||||
|
||||
// Read RadioStation
|
||||
RadioStation=m.ReadByte();
|
||||
RadioStation = m.ReadByte();
|
||||
|
||||
LicensePlate=m.ReadString();
|
||||
LicensePlate = m.ReadString();
|
||||
|
||||
Livery=(int)(m.ReadByte()-1);
|
||||
Livery = m.ReadByte() - 1;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Lidgren.Network;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace RageCoop.Core.Scripting
|
||||
{
|
||||
@ -10,8 +10,8 @@ namespace RageCoop.Core.Scripting
|
||||
/// </summary>
|
||||
public static class CustomEvents
|
||||
{
|
||||
static MD5 Hasher = MD5.Create();
|
||||
static Dictionary<int,string> Hashed=new Dictionary<int,string>();
|
||||
private static readonly MD5 Hasher = MD5.Create();
|
||||
private static readonly Dictionary<int, string> Hashed = new Dictionary<int, string>();
|
||||
internal static readonly int OnPlayerDied = Hash("RageCoop.OnPlayerDied");
|
||||
internal static readonly int SetWeather = Hash("RageCoop.SetWeather");
|
||||
internal static readonly int OnPedDeleted = Hash("RageCoop.OnPedDeleted");
|
||||
@ -40,12 +40,11 @@ namespace RageCoop.Core.Scripting
|
||||
public static int Hash(string s)
|
||||
{
|
||||
var hash = BitConverter.ToInt32(Hasher.ComputeHash(Encoding.UTF8.GetBytes(s)), 0);
|
||||
string name;
|
||||
lock (Hashed)
|
||||
{
|
||||
if (Hashed.TryGetValue(hash, out name))
|
||||
if (Hashed.TryGetValue(hash, out string name))
|
||||
{
|
||||
if (name!=s)
|
||||
if (name != s)
|
||||
{
|
||||
throw new ArgumentException($"Hashed value has collision with another name:{name}, hashed value:{hash}");
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace RageCoop.Core.Scripting
|
||||
|
@ -1,17 +1,17 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// A worker that constantly execute jobs in a background thread.
|
||||
/// </summary>
|
||||
public class Worker:IDisposable
|
||||
public class Worker : IDisposable
|
||||
{
|
||||
private SemaphoreSlim _semaphoreSlim;
|
||||
private Thread _workerThread;
|
||||
private bool _stopping=false;
|
||||
private readonly SemaphoreSlim _semaphoreSlim;
|
||||
private readonly Thread _workerThread;
|
||||
private bool _stopping = false;
|
||||
/// <summary>
|
||||
/// Name of the worker
|
||||
/// </summary>
|
||||
@ -19,20 +19,20 @@ namespace RageCoop.Core
|
||||
/// <summary>
|
||||
/// Whether this worker is busy executing job(s).
|
||||
/// </summary>
|
||||
public bool IsBusy { get;private set; }
|
||||
internal Worker(string name,Logger logger,int maxJobs = Int32.MaxValue)
|
||||
public bool IsBusy { get; private set; }
|
||||
internal Worker(string name, Logger logger, int maxJobs = Int32.MaxValue)
|
||||
{
|
||||
Name = name;
|
||||
_semaphoreSlim = new SemaphoreSlim(0,maxJobs);
|
||||
_workerThread=new Thread(() =>
|
||||
_semaphoreSlim = new SemaphoreSlim(0, maxJobs);
|
||||
_workerThread = new Thread(() =>
|
||||
{
|
||||
while (!_stopping)
|
||||
{
|
||||
IsBusy=false;
|
||||
IsBusy = false;
|
||||
_semaphoreSlim.Wait();
|
||||
if(Jobs.TryDequeue(out var job))
|
||||
if (Jobs.TryDequeue(out var job))
|
||||
{
|
||||
IsBusy=true;
|
||||
IsBusy = true;
|
||||
try
|
||||
{
|
||||
job.Invoke();
|
||||
@ -48,7 +48,7 @@ namespace RageCoop.Core
|
||||
throw new InvalidOperationException("Hmm... that's unexpected.");
|
||||
}
|
||||
}
|
||||
IsBusy=false;
|
||||
IsBusy = false;
|
||||
});
|
||||
_workerThread.Start();
|
||||
}
|
||||
@ -66,7 +66,7 @@ namespace RageCoop.Core
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
_stopping=true;
|
||||
_stopping = true;
|
||||
QueueJob(() => { });
|
||||
if (_workerThread.IsAlive)
|
||||
{
|
||||
@ -81,6 +81,6 @@ namespace RageCoop.Core
|
||||
Stop();
|
||||
_semaphoreSlim.Dispose();
|
||||
}
|
||||
private ConcurrentQueue<Action> Jobs=new ConcurrentQueue<Action>();
|
||||
private readonly ConcurrentQueue<Action> Jobs = new ConcurrentQueue<Action>();
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Core;
|
||||
using Lidgren.Network;
|
||||
using System.Diagnostics;
|
||||
using RageCoop.Core.Scripting;
|
||||
using System.Security.Cryptography;
|
||||
using RageCoop.Server.Scripting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace RageCoop.Server
|
||||
{
|
||||
@ -18,7 +18,7 @@ namespace RageCoop.Server
|
||||
private readonly Server Server;
|
||||
internal Client(Server server)
|
||||
{
|
||||
Server=server;
|
||||
Server = server;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -36,7 +36,7 @@ namespace RageCoop.Server
|
||||
public IPEndPoint InternalEndPoint { get; internal set; }
|
||||
|
||||
internal long NetHandle = 0;
|
||||
internal NetConnection Connection { get;set; }
|
||||
internal NetConnection Connection { get; set; }
|
||||
/// <summary>
|
||||
/// The <see cref="ServerPed"/> instance representing the client's main character.
|
||||
/// </summary>
|
||||
@ -44,34 +44,36 @@ namespace RageCoop.Server
|
||||
/// <summary>
|
||||
/// The client's latency in seconds.
|
||||
/// </summary>
|
||||
public float Latency => Connection.AverageRoundtripTime/2;
|
||||
public float Latency => Connection.AverageRoundtripTime / 2;
|
||||
internal readonly Dictionary<int, Action<object>> Callbacks = new();
|
||||
internal byte[] PublicKey { get; set; }
|
||||
/// <summary>
|
||||
/// Indicates whether the client has succefully loaded all resources.
|
||||
/// </summary>
|
||||
public bool IsReady { get; internal set; }=false;
|
||||
public bool IsReady { get; internal set; } = false;
|
||||
/// <summary>
|
||||
/// The client's username.
|
||||
/// </summary>
|
||||
public string Username { get;internal set; } = "N/A";
|
||||
public string Username { get; internal set; } = "N/A";
|
||||
|
||||
|
||||
private bool _autoRespawn=true;
|
||||
private bool _autoRespawn = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether to enable automatic respawn for this client's main ped.
|
||||
/// </summary>
|
||||
public bool EnableAutoRespawn {
|
||||
public bool EnableAutoRespawn
|
||||
{
|
||||
get => _autoRespawn;
|
||||
set {
|
||||
BaseScript.SetAutoRespawn(this,value);
|
||||
_autoRespawn=value;
|
||||
set
|
||||
{
|
||||
BaseScript.SetAutoRespawn(this, value);
|
||||
_autoRespawn = value;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _displayNameTag=true;
|
||||
private Stopwatch _latencyWatch = new Stopwatch();
|
||||
private bool _displayNameTag = true;
|
||||
private readonly Stopwatch _latencyWatch = new Stopwatch();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether to enable automatic respawn for this client's main ped.
|
||||
@ -81,8 +83,8 @@ namespace RageCoop.Server
|
||||
get => _displayNameTag;
|
||||
set
|
||||
{
|
||||
Server.BaseScript.SetNameTag(this,value);
|
||||
_displayNameTag=value;
|
||||
Server.BaseScript.SetNameTag(this, value);
|
||||
_displayNameTag = value;
|
||||
}
|
||||
}
|
||||
#region FUNCTIONS
|
||||
@ -90,7 +92,7 @@ namespace RageCoop.Server
|
||||
/// Kick this client
|
||||
/// </summary>
|
||||
/// <param name="reason"></param>
|
||||
public void Kick(string reason="You have been kicked!")
|
||||
public void Kick(string reason = "You have been kicked!")
|
||||
{
|
||||
Connection?.Disconnect(reason);
|
||||
}
|
||||
@ -129,7 +131,7 @@ namespace RageCoop.Server
|
||||
/// <param name="args"></param>
|
||||
public void SendNativeCall<T>(Action<object> callBack, GTA.Native.Hash hash, params object[] args)
|
||||
{
|
||||
var argsList= new List<object>(args);
|
||||
var argsList = new List<object>(args);
|
||||
argsList.InsertRange(0, new object[] { (byte)Type.GetTypeCode(typeof(T)), RequestNativeCallID<T>(callBack), (ulong)hash });
|
||||
|
||||
SendCustomEventQueued(CustomEvents.NativeCall, argsList.ToArray());
|
||||
@ -142,7 +144,7 @@ namespace RageCoop.Server
|
||||
public void SendNativeCall(GTA.Native.Hash hash, params object[] args)
|
||||
{
|
||||
var argsList = new List<object>(args);
|
||||
argsList.InsertRange(0, new object[] { (byte)TypeCode.Empty,(ulong)hash });
|
||||
argsList.InsertRange(0, new object[] { (byte)TypeCode.Empty, (ulong)hash });
|
||||
// Server.Logger?.Debug(argsList.DumpWithType());
|
||||
SendCustomEventQueued(CustomEvents.NativeCall, argsList.ToArray());
|
||||
}
|
||||
@ -151,7 +153,7 @@ namespace RageCoop.Server
|
||||
int ID = 0;
|
||||
lock (Callbacks)
|
||||
{
|
||||
while ((ID==0)
|
||||
while ((ID == 0)
|
||||
|| Callbacks.ContainsKey(ID))
|
||||
{
|
||||
byte[] rngBytes = new byte[4];
|
||||
@ -170,7 +172,7 @@ namespace RageCoop.Server
|
||||
/// </summary>
|
||||
/// <param name="hash">An unique identifier of the event, you can use <see cref="CustomEvents.Hash(string)"/> to get it from a string</param>
|
||||
/// <param name="args">Arguments</param>
|
||||
public void SendCustomEvent(int hash,params object[] args)
|
||||
public void SendCustomEvent(int hash, params object[] args)
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
@ -183,8 +185,8 @@ namespace RageCoop.Server
|
||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||
new Packets.CustomEvent()
|
||||
{
|
||||
Hash=hash,
|
||||
Args=args
|
||||
Hash = hash,
|
||||
Args = args
|
||||
}.Pack(outgoingMessage);
|
||||
Server.MainNetServer.SendMessage(outgoingMessage, Connection, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Event);
|
||||
|
||||
@ -211,10 +213,10 @@ namespace RageCoop.Server
|
||||
{
|
||||
|
||||
NetOutgoingMessage outgoingMessage = Server.MainNetServer.CreateMessage();
|
||||
new Packets.CustomEvent(null,true)
|
||||
new Packets.CustomEvent(null, true)
|
||||
{
|
||||
Hash=hash,
|
||||
Args=args
|
||||
Hash = hash,
|
||||
Args = args
|
||||
}.Pack(outgoingMessage);
|
||||
Server.MainNetServer.SendMessage(outgoingMessage, Connection, NetDeliveryMethod.ReliableOrdered, (byte)ConnectionChannel.Event);
|
||||
|
||||
|
@ -1,16 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RageCoop.Server
|
||||
namespace RageCoop.Server
|
||||
{
|
||||
internal class FileTransfer
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public float Progress { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool Cancel { get; set; }=false;
|
||||
public bool Cancel { get; set; } = false;
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
using RageCoop.Core;
|
||||
namespace RageCoop.Server
|
||||
namespace RageCoop.Server
|
||||
{
|
||||
internal class HolePunch
|
||||
{
|
||||
|
@ -1,25 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using Lidgren.Network;
|
||||
using Newtonsoft.Json;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Server.Scripting;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using Newtonsoft.Json;
|
||||
using RageCoop.Core.Scripting;
|
||||
using RageCoop.Server.Scripting;
|
||||
using System.Threading;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.IO;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace RageCoop.Server
|
||||
{
|
||||
public partial class Server
|
||||
{
|
||||
const string _versionURL = "https://raw.githubusercontent.com/RAGECOOP/RAGECOOP-V/main/RageCoop.Server/Properties/AssemblyInfo.cs";
|
||||
private const string _versionURL = "https://raw.githubusercontent.com/RAGECOOP/RAGECOOP-V/main/RageCoop.Server/Properties/AssemblyInfo.cs";
|
||||
private void SendPlayerUpdate()
|
||||
{
|
||||
foreach (var c in ClientsByNetHandle.Values.ToArray())
|
||||
@ -157,18 +155,18 @@ namespace RageCoop.Server
|
||||
MainNetServer.Shutdown("Server updating");
|
||||
Logger.Info("Server shutting down!");
|
||||
Logger.Flush();
|
||||
Process.Start(Path.Combine("Update", RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "RageCoop.Server.exe": "RageCoop.Server"), "update \"" + AppDomain.CurrentDomain.BaseDirectory[0..^1] + "\"");
|
||||
Process.Start(Path.Combine("Update", RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "RageCoop.Server.exe" : "RageCoop.Server"), "update \"" + AppDomain.CurrentDomain.BaseDirectory[0..^1] + "\"");
|
||||
Environment.Exit(0);
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger?.Error("Update",ex);
|
||||
Logger?.Error("Update", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void KickAssholes()
|
||||
{
|
||||
foreach(var c in ClientsByNetHandle.Values.ToArray())
|
||||
foreach (var c in ClientsByNetHandle.Values.ToArray())
|
||||
{
|
||||
if (c.EntitiesCount > Settings.SpamLimit && Settings.KickSpamming)
|
||||
{
|
||||
|
@ -1,12 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Lidgren.Network;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
using RageCoop.Server.Scripting;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace RageCoop.Server
|
||||
{
|
||||
@ -50,10 +48,10 @@ namespace RageCoop.Server
|
||||
|
||||
var args = new HandshakeEventArgs()
|
||||
{
|
||||
EndPoint=connection.RemoteEndPoint,
|
||||
ID=packet.PedID,
|
||||
Username=packet.Username,
|
||||
PasswordHash=Security.Decrypt(packet.PasswordEncrypted, connection.RemoteEndPoint).GetString().GetSHA256Hash().ToHexString(),
|
||||
EndPoint = connection.RemoteEndPoint,
|
||||
ID = packet.PedID,
|
||||
Username = packet.Username,
|
||||
PasswordHash = Security.Decrypt(packet.PasswordEncrypted, connection.RemoteEndPoint).GetString().GetSHA256Hash().ToHexString(),
|
||||
};
|
||||
API.Events.InvokePlayerHandshake(args);
|
||||
if (args.Cancel)
|
||||
@ -73,18 +71,18 @@ namespace RageCoop.Server
|
||||
var handshakeSuccess = MainNetServer.CreateMessage();
|
||||
var currentClients = ClientsByID.Values.ToArray();
|
||||
var players = new Packets.PlayerData[currentClients.Length];
|
||||
for (int i = 0; i<players.Length; i++)
|
||||
for (int i = 0; i < players.Length; i++)
|
||||
{
|
||||
players[i]=new Packets.PlayerData()
|
||||
players[i] = new Packets.PlayerData()
|
||||
{
|
||||
ID=currentClients[i].Player.ID,
|
||||
Username=currentClients[i].Username,
|
||||
ID = currentClients[i].Player.ID,
|
||||
Username = currentClients[i].Username,
|
||||
};
|
||||
}
|
||||
|
||||
new Packets.HandshakeSuccess()
|
||||
{
|
||||
Players=players
|
||||
Players = players
|
||||
}.Pack(handshakeSuccess);
|
||||
connection.Approve(handshakeSuccess);
|
||||
Client tmpClient;
|
||||
@ -94,25 +92,25 @@ namespace RageCoop.Server
|
||||
{
|
||||
var player = new ServerPed(this)
|
||||
{
|
||||
ID= packet.PedID,
|
||||
ID = packet.PedID,
|
||||
};
|
||||
Entities.Add(player);
|
||||
ClientsByNetHandle.Add(connection.RemoteUniqueIdentifier,
|
||||
tmpClient = new Client(this)
|
||||
{
|
||||
NetHandle = connection.RemoteUniqueIdentifier,
|
||||
Connection=connection,
|
||||
Username=packet.Username,
|
||||
Connection = connection,
|
||||
Username = packet.Username,
|
||||
Player = player,
|
||||
InternalEndPoint=packet.InternalEndPoint,
|
||||
InternalEndPoint = packet.InternalEndPoint,
|
||||
}
|
||||
);
|
||||
player.Owner=tmpClient;
|
||||
player.Owner = tmpClient;
|
||||
ClientsByName.Add(packet.Username.ToLower(), tmpClient);
|
||||
ClientsByID.Add(player.ID, tmpClient);
|
||||
if (ClientsByNetHandle.Count==1)
|
||||
if (ClientsByNetHandle.Count == 1)
|
||||
{
|
||||
_hostClient=tmpClient;
|
||||
_hostClient = tmpClient;
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,19 +121,19 @@ namespace RageCoop.Server
|
||||
// The connection has been approved, now we need to send all other players to the new player and the new player to all players
|
||||
private void PlayerConnected(Client newClient)
|
||||
{
|
||||
if (newClient==_hostClient)
|
||||
if (newClient == _hostClient)
|
||||
{
|
||||
API.SendCustomEvent(new() { newClient }, CustomEvents.IsHost, true);
|
||||
}
|
||||
|
||||
// Send new client to all players
|
||||
var cons = MainNetServer.Connections.Exclude(newClient.Connection);
|
||||
if (cons.Count!=0)
|
||||
if (cons.Count != 0)
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
new Packets.PlayerConnect()
|
||||
{
|
||||
PedID=newClient.Player.ID,
|
||||
PedID = newClient.Player.ID,
|
||||
Username = newClient.Username
|
||||
}.Pack(outgoingMessage);
|
||||
|
||||
@ -154,8 +152,8 @@ namespace RageCoop.Server
|
||||
{
|
||||
ClientsByNetHandle.Values.ForEach(target =>
|
||||
{
|
||||
if (target==newClient) { return; }
|
||||
HolePunch(target,newClient);
|
||||
if (target == newClient) { return; }
|
||||
HolePunch(target, newClient);
|
||||
});
|
||||
}
|
||||
|
||||
@ -171,12 +169,12 @@ namespace RageCoop.Server
|
||||
private void PlayerDisconnected(Client localClient)
|
||||
{
|
||||
var cons = MainNetServer.Connections.Exclude(localClient.Connection);
|
||||
if (cons.Count!=0)
|
||||
if (cons.Count != 0)
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
new Packets.PlayerDisconnect()
|
||||
{
|
||||
PedID=localClient.Player.ID,
|
||||
PedID = localClient.Player.ID,
|
||||
|
||||
}.Pack(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, cons, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
@ -187,7 +185,7 @@ namespace RageCoop.Server
|
||||
if (ClientsByNetHandle.ContainsKey(localClient.NetHandle)) { ClientsByNetHandle.Remove(localClient.NetHandle); }
|
||||
if (ClientsByName.ContainsKey(localClient.Username.ToLower())) { ClientsByName.Remove(localClient.Username.ToLower()); }
|
||||
if (ClientsByID.ContainsKey(localClient.Player.ID)) { ClientsByID.Remove(localClient.Player.ID); }
|
||||
if (localClient==_hostClient)
|
||||
if (localClient == _hostClient)
|
||||
{
|
||||
|
||||
_hostClient = ClientsByNetHandle.Values.FirstOrDefault();
|
||||
|
@ -1,11 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Lidgren.Network;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
using RageCoop.Server.Scripting;
|
||||
|
||||
namespace RageCoop.Server
|
||||
@ -16,7 +10,7 @@ namespace RageCoop.Server
|
||||
{
|
||||
QueueJob(() => Entities.Update(packet, client));
|
||||
|
||||
bool isPlayer = packet.ID==client.Player.ID;
|
||||
bool isPlayer = packet.ID == client.Player.ID;
|
||||
if (isPlayer)
|
||||
{
|
||||
QueueJob(() => API.Events.InvokePlayerUpdate(client));
|
||||
@ -27,17 +21,17 @@ namespace RageCoop.Server
|
||||
{
|
||||
|
||||
// Don't send data back
|
||||
if (c.NetHandle==client.NetHandle) { continue; }
|
||||
if (c.NetHandle == client.NetHandle) { continue; }
|
||||
|
||||
// Check streaming distance
|
||||
if (isPlayer)
|
||||
{
|
||||
if ((Settings.PlayerStreamingDistance!=-1)&&(packet.Position.DistanceTo(c.Player.Position)>Settings.PlayerStreamingDistance))
|
||||
if ((Settings.PlayerStreamingDistance != -1) && (packet.Position.DistanceTo(c.Player.Position) > Settings.PlayerStreamingDistance))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ((Settings.NpcStreamingDistance!=-1)&&(packet.Position.DistanceTo(c.Player.Position)>Settings.NpcStreamingDistance))
|
||||
else if ((Settings.NpcStreamingDistance != -1) && (packet.Position.DistanceTo(c.Player.Position) > Settings.NpcStreamingDistance))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -50,22 +44,22 @@ namespace RageCoop.Server
|
||||
private void VehicleSync(Packets.VehicleSync packet, Client client)
|
||||
{
|
||||
QueueJob(() => Entities.Update(packet, client));
|
||||
bool isPlayer = packet.ID==client.Player?.LastVehicle?.ID;
|
||||
bool isPlayer = packet.ID == client.Player?.LastVehicle?.ID;
|
||||
|
||||
|
||||
if (Settings.UseP2P) { return; }
|
||||
foreach (var c in ClientsByNetHandle.Values)
|
||||
{
|
||||
if (c.NetHandle==client.NetHandle) { continue; }
|
||||
if (c.NetHandle == client.NetHandle) { continue; }
|
||||
if (isPlayer)
|
||||
{
|
||||
// Player's vehicle
|
||||
if ((Settings.PlayerStreamingDistance!=-1)&&(packet.Position.DistanceTo(c.Player.Position)>Settings.PlayerStreamingDistance))
|
||||
if ((Settings.PlayerStreamingDistance != -1) && (packet.Position.DistanceTo(c.Player.Position) > Settings.PlayerStreamingDistance))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if ((Settings.NpcStreamingDistance!=-1)&&(packet.Position.DistanceTo(c.Player.Position)>Settings.NpcStreamingDistance))
|
||||
else if ((Settings.NpcStreamingDistance != -1) && (packet.Position.DistanceTo(c.Player.Position) > Settings.NpcStreamingDistance))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
@ -1,12 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Lidgren.Network;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
using RageCoop.Server.Scripting;
|
||||
|
||||
namespace RageCoop.Server
|
||||
{
|
||||
@ -17,19 +10,19 @@ namespace RageCoop.Server
|
||||
// Send to host
|
||||
Send(new Packets.HolePunchInit
|
||||
{
|
||||
Connect=false,
|
||||
TargetID=client.Player.ID,
|
||||
TargetInternal=client.InternalEndPoint.ToString(),
|
||||
TargetExternal=client.EndPoint.ToString()
|
||||
Connect = false,
|
||||
TargetID = client.Player.ID,
|
||||
TargetInternal = client.InternalEndPoint.ToString(),
|
||||
TargetExternal = client.EndPoint.ToString()
|
||||
}, host, ConnectionChannel.Default, NetDeliveryMethod.ReliableOrdered);
|
||||
|
||||
// Send to client
|
||||
Send(new Packets.HolePunchInit
|
||||
{
|
||||
Connect=true,
|
||||
TargetID=host.Player.ID,
|
||||
TargetInternal=host.InternalEndPoint.ToString(),
|
||||
TargetExternal=host.EndPoint.ToString()
|
||||
Connect = true,
|
||||
TargetID = host.Player.ID,
|
||||
TargetInternal = host.InternalEndPoint.ToString(),
|
||||
TargetExternal = host.EndPoint.ToString()
|
||||
}, client, ConnectionChannel.Default, NetDeliveryMethod.ReliableOrdered);
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Lidgren.Network;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
using RageCoop.Server.Scripting;
|
||||
using System;
|
||||
|
||||
namespace RageCoop.Server
|
||||
{
|
||||
@ -141,7 +136,7 @@ namespace RageCoop.Server
|
||||
{
|
||||
var outgoingMessage = MainNetServer.CreateMessage();
|
||||
outgoingMessage.Write((byte)type);
|
||||
outgoingMessage.Write(message.ReadBytes(message.LengthBytes-1));
|
||||
outgoingMessage.Write(message.ReadBytes(message.LengthBytes - 1));
|
||||
MainNetServer.SendMessage(outgoingMessage, toSend, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.SyncEvents);
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,16 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Core;
|
||||
using Newtonsoft.Json;
|
||||
using Lidgren.Network;
|
||||
using System.Timers;
|
||||
using System.Security.Cryptography;
|
||||
using RageCoop.Server.Scripting;
|
||||
using Timer = System.Timers.Timer;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using RageCoop.Core.Scripting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Timer = System.Timers.Timer;
|
||||
|
||||
namespace RageCoop.Server
|
||||
{
|
||||
@ -38,12 +30,12 @@ namespace RageCoop.Server
|
||||
internal ServerEntities Entities;
|
||||
|
||||
internal readonly Dictionary<Command, Action<CommandContext>> Commands = new();
|
||||
internal readonly Dictionary<long,Client> ClientsByNetHandle = new();
|
||||
internal readonly Dictionary<long, Client> ClientsByNetHandle = new();
|
||||
internal readonly Dictionary<string, Client> ClientsByName = new();
|
||||
internal readonly Dictionary<int, Client> ClientsByID = new();
|
||||
internal Client _hostClient;
|
||||
|
||||
private Dictionary<int,FileTransfer> InProgressFileTransfers=new();
|
||||
private readonly Dictionary<int, FileTransfer> InProgressFileTransfers = new();
|
||||
internal Resources Resources;
|
||||
internal Logger Logger;
|
||||
internal Security Security;
|
||||
@ -55,8 +47,8 @@ namespace RageCoop.Server
|
||||
private readonly Timer _updateTimer = new();
|
||||
private readonly Worker _worker;
|
||||
private readonly HashSet<char> _allowedCharacterSet;
|
||||
private Dictionary<int,Action<PacketType,NetIncomingMessage>> PendingResponses=new();
|
||||
internal Dictionary<PacketType, Func<NetIncomingMessage,Client,Packet>> RequestHandlers=new();
|
||||
private readonly Dictionary<int, Action<PacketType, NetIncomingMessage>> PendingResponses = new();
|
||||
internal Dictionary<PacketType, Func<NetIncomingMessage, Client, Packet>> RequestHandlers = new();
|
||||
/// <summary>
|
||||
/// Get the current server version
|
||||
/// </summary>
|
||||
@ -67,23 +59,23 @@ namespace RageCoop.Server
|
||||
/// <param name="settings"></param>
|
||||
/// <param name="logger"></param>
|
||||
/// <exception cref="ArgumentNullException"></exception>
|
||||
public Server(Settings settings,Logger logger=null)
|
||||
public Server(Settings settings, Logger logger = null)
|
||||
{
|
||||
Settings = settings;
|
||||
if (settings==null) { throw new ArgumentNullException("Server settings cannot be null!"); }
|
||||
Logger=logger;
|
||||
if (Logger!=null) { Logger.LogLevel=Settings.LogLevel;}
|
||||
API=new API(this);
|
||||
Resources=new Resources(this);
|
||||
Security=new Security(Logger);
|
||||
Entities=new ServerEntities(this);
|
||||
BaseScript=new BaseScript(this);
|
||||
_allowedCharacterSet=new HashSet<char>(Settings.AllowedUsernameChars.ToCharArray());
|
||||
if (settings == null) { throw new ArgumentNullException("Server settings cannot be null!"); }
|
||||
Logger = logger;
|
||||
if (Logger != null) { Logger.LogLevel = Settings.LogLevel; }
|
||||
API = new API(this);
|
||||
Resources = new Resources(this);
|
||||
Security = new Security(Logger);
|
||||
Entities = new ServerEntities(this);
|
||||
BaseScript = new BaseScript(this);
|
||||
_allowedCharacterSet = new HashSet<char>(Settings.AllowedUsernameChars.ToCharArray());
|
||||
|
||||
|
||||
_worker=new Worker("ServerWorker", Logger);
|
||||
_worker = new Worker("ServerWorker", Logger);
|
||||
|
||||
_listenerThread=new Thread(() => Listen());
|
||||
_listenerThread = new Thread(() => Listen());
|
||||
|
||||
_announceTimer.Interval = 1;
|
||||
_announceTimer.Elapsed += (s, e) =>
|
||||
@ -105,7 +97,7 @@ namespace RageCoop.Server
|
||||
_updateTimer.Interval = 1;
|
||||
_updateTimer.Elapsed += (s, e) =>
|
||||
{
|
||||
_updateTimer.Interval= 1000 * 60 * 10; // 10 minutes
|
||||
_updateTimer.Interval = 1000 * 60 * 10; // 10 minutes
|
||||
_updateTimer.Stop();
|
||||
CheckUpdate();
|
||||
_updateTimer.Start();
|
||||
@ -137,8 +129,8 @@ namespace RageCoop.Server
|
||||
}
|
||||
if (Settings.UseZeroTier)
|
||||
{
|
||||
Logger?.Info($"Joining ZeroTier network: "+Settings.ZeroTierNetworkID);
|
||||
if (ZeroTierHelper.Join(Settings.ZeroTierNetworkID)==null)
|
||||
Logger?.Info($"Joining ZeroTier network: " + Settings.ZeroTierNetworkID);
|
||||
if (ZeroTierHelper.Join(Settings.ZeroTierNetworkID) == null)
|
||||
{
|
||||
throw new Exception("Failed to obtain ZeroTier network IP");
|
||||
}
|
||||
@ -155,7 +147,7 @@ namespace RageCoop.Server
|
||||
MaximumConnections = Settings.MaxPlayers,
|
||||
EnableUPnP = false,
|
||||
AutoFlushSendQueue = true,
|
||||
PingInterval=5
|
||||
PingInterval = 5
|
||||
};
|
||||
|
||||
config.EnableMessageType(NetIncomingMessageType.ConnectionApproval);
|
||||
@ -163,16 +155,16 @@ namespace RageCoop.Server
|
||||
|
||||
MainNetServer = new NetServer(config);
|
||||
MainNetServer.Start();
|
||||
BaseScript.API=API;
|
||||
BaseScript.API = API;
|
||||
BaseScript.OnStart();
|
||||
Resources.LoadAll();
|
||||
_listenerThread.Start();
|
||||
Logger?.Info("Listening for clients");
|
||||
|
||||
_playerUpdateTimer.Enabled=true;
|
||||
_playerUpdateTimer.Enabled = true;
|
||||
if (Settings.AnnounceSelf)
|
||||
{
|
||||
_announceTimer.Enabled=true;
|
||||
_announceTimer.Enabled = true;
|
||||
}
|
||||
if (Settings.AutoUpdate)
|
||||
{
|
||||
@ -201,20 +193,20 @@ namespace RageCoop.Server
|
||||
}
|
||||
|
||||
// Send a message to targets or all players
|
||||
internal void ChatMessageReceived(string name, string message,Client sender=null)
|
||||
internal void ChatMessageReceived(string name, string message, Client sender = null)
|
||||
{
|
||||
if (message.StartsWith('/'))
|
||||
{
|
||||
string[] cmdArgs = message.Split(" ");
|
||||
string cmdName = cmdArgs[0].Remove(0, 1);
|
||||
QueueJob(()=>API.Events.InvokeOnCommandReceived(cmdName, cmdArgs, sender));
|
||||
QueueJob(() => API.Events.InvokeOnCommandReceived(cmdName, cmdArgs, sender));
|
||||
return;
|
||||
}
|
||||
message = message.Replace("~", "");
|
||||
|
||||
QueueJob(() => API.Events.InvokeOnChatMessage(message, sender));
|
||||
|
||||
foreach(var c in ClientsByNetHandle.Values)
|
||||
foreach (var c in ClientsByNetHandle.Values)
|
||||
{
|
||||
var msg = MainNetServer.CreateMessage();
|
||||
var crypt = new Func<string, byte[]>((s) =>
|
||||
@ -223,23 +215,23 @@ namespace RageCoop.Server
|
||||
});
|
||||
new Packets.ChatMessage(crypt)
|
||||
{
|
||||
Username=name,
|
||||
Message=message
|
||||
Username = name,
|
||||
Message = message
|
||||
}.Pack(msg);
|
||||
MainNetServer.SendMessage(msg,c.Connection, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Chat);
|
||||
MainNetServer.SendMessage(msg, c.Connection, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Chat);
|
||||
}
|
||||
}
|
||||
internal void SendChatMessage(string name, string message, Client target)
|
||||
{
|
||||
if(target == null) { return; }
|
||||
if (target == null) { return; }
|
||||
var msg = MainNetServer.CreateMessage();
|
||||
new Packets.ChatMessage(new Func<string, byte[]>((s) =>
|
||||
{
|
||||
return Security.Encrypt(s.GetBytes(), target.EndPoint);
|
||||
}))
|
||||
{
|
||||
Username= name,
|
||||
Message=message,
|
||||
Username = name,
|
||||
Message = message,
|
||||
}.Pack(msg);
|
||||
MainNetServer.SendMessage(msg, target.Connection, NetDeliveryMethod.ReliableOrdered, (int)ConnectionChannel.Chat);
|
||||
}
|
||||
@ -278,17 +270,17 @@ namespace RageCoop.Server
|
||||
RegisterCommand(attribute.Name, attribute.Usage, attribute.ArgsLength, (Action<CommandContext>)Delegate.CreateDelegate(typeof(Action<CommandContext>), method));
|
||||
}
|
||||
}
|
||||
internal T GetResponse<T>(Client client,Packet request, ConnectionChannel channel = ConnectionChannel.RequestResponse,int timeout=5000) where T:Packet, new()
|
||||
internal T GetResponse<T>(Client client, Packet request, ConnectionChannel channel = ConnectionChannel.RequestResponse, int timeout = 5000) where T : Packet, new()
|
||||
{
|
||||
if (Thread.CurrentThread==_listenerThread)
|
||||
if (Thread.CurrentThread == _listenerThread)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot wait for response from the listener thread!");
|
||||
}
|
||||
|
||||
var received =new AutoResetEvent(false);
|
||||
T response=new T();
|
||||
var received = new AutoResetEvent(false);
|
||||
T response = new T();
|
||||
var id = NewRequestID();
|
||||
PendingResponses.Add(id, (type,m) =>
|
||||
PendingResponses.Add(id, (type, m) =>
|
||||
{
|
||||
response.Deserialize(m);
|
||||
received.Set();
|
||||
@ -297,7 +289,7 @@ namespace RageCoop.Server
|
||||
msg.Write((byte)PacketType.Request);
|
||||
msg.Write(id);
|
||||
request.Pack(msg);
|
||||
MainNetServer.SendMessage(msg,client.Connection,NetDeliveryMethod.ReliableOrdered,(int)channel);
|
||||
MainNetServer.SendMessage(msg, client.Connection, NetDeliveryMethod.ReliableOrdered, (int)channel);
|
||||
if (received.WaitOne(timeout))
|
||||
{
|
||||
return response;
|
||||
@ -305,25 +297,25 @@ namespace RageCoop.Server
|
||||
|
||||
return null;
|
||||
}
|
||||
internal void SendFile(string path,string name,Client client,Action<float> updateCallback=null)
|
||||
internal void SendFile(string path, string name, Client client, Action<float> updateCallback = null)
|
||||
{
|
||||
var fs = File.OpenRead(path);
|
||||
SendFile(fs, name,client,NewFileID(),updateCallback);
|
||||
SendFile(fs, name, client, NewFileID(), updateCallback);
|
||||
fs.Close();
|
||||
fs.Dispose();
|
||||
}
|
||||
internal void SendFile(Stream stream, string name, Client client,int id=default, Action<float> updateCallback = null)
|
||||
internal void SendFile(Stream stream, string name, Client client, int id = default, Action<float> updateCallback = null)
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
id = id ==default? NewFileID(): id ;
|
||||
id = id == default ? NewFileID() : id;
|
||||
var total = stream.Length;
|
||||
Logger?.Debug($"Requesting file transfer:{name}, {total}");
|
||||
if (GetResponse<Packets.FileTransferResponse>(client, new Packets.FileTransferRequest()
|
||||
{
|
||||
FileLength= total,
|
||||
Name=name,
|
||||
ID=id,
|
||||
}, ConnectionChannel.File)?.Response!=FileResponse.NeedToDownload)
|
||||
FileLength = total,
|
||||
Name = name,
|
||||
ID = id,
|
||||
}, ConnectionChannel.File)?.Response != FileResponse.NeedToDownload)
|
||||
{
|
||||
Logger?.Info($"Skipping file transfer \"{name}\" to {client.Username}");
|
||||
return;
|
||||
@ -331,7 +323,7 @@ namespace RageCoop.Server
|
||||
Logger?.Debug($"Initiating file transfer:{name}, {total}");
|
||||
FileTransfer transfer = new()
|
||||
{
|
||||
ID=id,
|
||||
ID = id,
|
||||
Name = name,
|
||||
};
|
||||
InProgressFileTransfers.Add(id, transfer);
|
||||
@ -341,30 +333,30 @@ namespace RageCoop.Server
|
||||
{
|
||||
// 4 KB chunk
|
||||
byte[] chunk = new byte[4096];
|
||||
read += thisRead=stream.Read(chunk, 0, 4096);
|
||||
if (thisRead!=chunk.Length)
|
||||
read += thisRead = stream.Read(chunk, 0, 4096);
|
||||
if (thisRead != chunk.Length)
|
||||
{
|
||||
if (thisRead==0) { break; }
|
||||
if (thisRead == 0) { break; }
|
||||
Logger?.Trace($"Purging chunk:{thisRead}");
|
||||
Array.Resize(ref chunk, thisRead);
|
||||
}
|
||||
Send(
|
||||
new Packets.FileTransferChunk()
|
||||
{
|
||||
ID=id,
|
||||
FileChunk=chunk,
|
||||
ID = id,
|
||||
FileChunk = chunk,
|
||||
},
|
||||
client, ConnectionChannel.File, NetDeliveryMethod.ReliableOrdered);
|
||||
transfer.Progress=read/stream.Length;
|
||||
if (updateCallback!=null) { updateCallback(transfer.Progress); }
|
||||
transfer.Progress = read / stream.Length;
|
||||
if (updateCallback != null) { updateCallback(transfer.Progress); }
|
||||
|
||||
} while (thisRead>0);
|
||||
} while (thisRead > 0);
|
||||
if (GetResponse<Packets.FileTransferResponse>(client, new Packets.FileTransferComplete()
|
||||
{
|
||||
ID= id,
|
||||
}, ConnectionChannel.File)?.Response!=FileResponse.Completed)
|
||||
ID = id,
|
||||
}, ConnectionChannel.File)?.Response != FileResponse.Completed)
|
||||
{
|
||||
Logger.Warning($"File trasfer to {client.Username} failed: "+name);
|
||||
Logger.Warning($"File trasfer to {client.Username} failed: " + name);
|
||||
}
|
||||
Logger?.Debug($"All file chunks sent:{name}");
|
||||
InProgressFileTransfers.Remove(id);
|
||||
@ -372,7 +364,7 @@ namespace RageCoop.Server
|
||||
internal int NewFileID()
|
||||
{
|
||||
int ID = 0;
|
||||
while ((ID==0)
|
||||
while ((ID == 0)
|
||||
|| InProgressFileTransfers.ContainsKey(ID))
|
||||
{
|
||||
byte[] rngBytes = new byte[4];
|
||||
@ -387,7 +379,7 @@ namespace RageCoop.Server
|
||||
private int NewRequestID()
|
||||
{
|
||||
int ID = 0;
|
||||
while ((ID==0)
|
||||
while ((ID == 0)
|
||||
|| PendingResponses.ContainsKey(ID))
|
||||
{
|
||||
byte[] rngBytes = new byte[4];
|
||||
@ -399,11 +391,11 @@ namespace RageCoop.Server
|
||||
}
|
||||
return ID;
|
||||
}
|
||||
internal void Send(Packet p,Client client, ConnectionChannel channel = ConnectionChannel.Default, NetDeliveryMethod method = NetDeliveryMethod.UnreliableSequenced)
|
||||
internal void Send(Packet p, Client client, ConnectionChannel channel = ConnectionChannel.Default, NetDeliveryMethod method = NetDeliveryMethod.UnreliableSequenced)
|
||||
{
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
p.Pack(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, client.Connection,method,(int)channel);
|
||||
MainNetServer.SendMessage(outgoingMessage, client.Connection, method, (int)channel);
|
||||
}
|
||||
internal void Forward(Packet p, Client except, ConnectionChannel channel = ConnectionChannel.Default, NetDeliveryMethod method = NetDeliveryMethod.UnreliableSequenced)
|
||||
{
|
||||
|
@ -1,21 +1,19 @@
|
||||
using System;
|
||||
using RageCoop.Core;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using RageCoop.Core;
|
||||
using Newtonsoft.Json;
|
||||
using System.Linq;
|
||||
|
||||
namespace RageCoop.Server
|
||||
{
|
||||
class Program
|
||||
internal class Program
|
||||
{
|
||||
private static bool Stopping = false;
|
||||
static Logger mainLogger;
|
||||
static void Main(string[] args)
|
||||
private static Logger mainLogger;
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
if (args.Length>=2 && args[0]=="update")
|
||||
if (args.Length >= 2 && args[0] == "update")
|
||||
{
|
||||
var target = args[1];
|
||||
int i = 0;
|
||||
@ -23,13 +21,13 @@ namespace RageCoop.Server
|
||||
{
|
||||
try
|
||||
{
|
||||
Console.WriteLine("Applying update to "+target);
|
||||
Console.WriteLine("Applying update to " + target);
|
||||
|
||||
CoreUtils.CopyFilesRecursively(new(AppDomain.CurrentDomain.BaseDirectory), new(target));
|
||||
Process.Start(Path.Combine(target, "RageCoop.Server"));
|
||||
Environment.Exit(0);
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.ToString());
|
||||
Thread.Sleep(3000);
|
||||
@ -37,22 +35,22 @@ namespace RageCoop.Server
|
||||
}
|
||||
Environment.Exit(i);
|
||||
}
|
||||
AppDomain.CurrentDomain.UnhandledException+=UnhandledException;
|
||||
AppDomain.CurrentDomain.UnhandledException += UnhandledException;
|
||||
mainLogger = new Logger()
|
||||
{
|
||||
LogPath="RageCoop.Server.log",
|
||||
UseConsole=true,
|
||||
Name="Server"
|
||||
LogPath = "RageCoop.Server.log",
|
||||
UseConsole = true,
|
||||
Name = "Server"
|
||||
};
|
||||
try
|
||||
{
|
||||
Console.Title = "RAGECOOP";
|
||||
var setting = Util.Read<Settings>("Settings.xml");
|
||||
#if DEBUG
|
||||
setting.LogLevel=0;
|
||||
setting.LogLevel = 0;
|
||||
#endif
|
||||
var server = new Server(setting, mainLogger);
|
||||
Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
|
||||
Console.CancelKeyPress += delegate (object sender, ConsoleCancelEventArgs e)
|
||||
{
|
||||
mainLogger.Info("Initiating shutdown sequence...");
|
||||
mainLogger.Info("Press Ctrl+C again to commence an emergency shutdown.");
|
||||
@ -82,8 +80,8 @@ namespace RageCoop.Server
|
||||
while (true)
|
||||
{
|
||||
|
||||
var s=Console.ReadLine();
|
||||
if (!Stopping && s!=null)
|
||||
var s = Console.ReadLine();
|
||||
if (!Stopping && s != null)
|
||||
{
|
||||
server.ChatMessageReceived("Server", s, null);
|
||||
}
|
||||
@ -98,11 +96,11 @@ namespace RageCoop.Server
|
||||
|
||||
private static void UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||||
{
|
||||
mainLogger.Error($"Unhandled exception thrown from user thread",e.ExceptionObject as Exception);
|
||||
mainLogger.Error($"Unhandled exception thrown from user thread", e.ExceptionObject as Exception);
|
||||
mainLogger.Flush();
|
||||
}
|
||||
|
||||
static void Fatal(Exception e)
|
||||
private static void Fatal(Exception e)
|
||||
{
|
||||
mainLogger.Error(e);
|
||||
mainLogger.Error($"Fatal error occurred, server shutting down.");
|
||||
|
@ -15,7 +15,7 @@ using System.Resources;
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Version information
|
||||
[assembly: AssemblyVersion("1.5.3.176")]
|
||||
[assembly: AssemblyFileVersion("1.5.3.176")]
|
||||
[assembly: AssemblyVersion("1.5.3.178")]
|
||||
[assembly: AssemblyFileVersion("1.5.3.178")]
|
||||
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]
|
||||
|
||||
|
@ -1,13 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Lidgren.Network;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RageCoop.Server.Scripting
|
||||
{
|
||||
@ -54,14 +53,14 @@ namespace RageCoop.Server.Scripting
|
||||
public event EventHandler<Client> OnPlayerUpdate;
|
||||
internal void ClearHandlers()
|
||||
{
|
||||
OnChatMessage=null;
|
||||
OnPlayerHandshake=null;
|
||||
OnPlayerConnected=null;
|
||||
OnPlayerReady=null;
|
||||
OnPlayerDisconnected=null;
|
||||
OnChatMessage = null;
|
||||
OnPlayerHandshake = null;
|
||||
OnPlayerConnected = null;
|
||||
OnPlayerReady = null;
|
||||
OnPlayerDisconnected = null;
|
||||
// OnCustomEventReceived=null;
|
||||
OnCommandReceived=null;
|
||||
OnPlayerUpdate=null;
|
||||
OnCommandReceived = null;
|
||||
OnPlayerUpdate = null;
|
||||
}
|
||||
#region INVOKE
|
||||
internal void InvokePlayerHandshake(HandshakeEventArgs args)
|
||||
@ -70,9 +69,9 @@ namespace RageCoop.Server.Scripting
|
||||
{
|
||||
var args = new OnCommandEventArgs()
|
||||
{
|
||||
Name=cmdName,
|
||||
Args=cmdArgs,
|
||||
Client=sender
|
||||
Name = cmdName,
|
||||
Args = cmdArgs,
|
||||
Client = sender
|
||||
};
|
||||
OnCommandReceived?.Invoke(this, args);
|
||||
if (args.Cancel)
|
||||
@ -99,27 +98,26 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
}
|
||||
|
||||
internal void InvokeOnChatMessage(string msg, Client sender, string clamiedSender=null)
|
||||
internal void InvokeOnChatMessage(string msg, Client sender, string clamiedSender = null)
|
||||
{
|
||||
OnChatMessage?.Invoke(this, new ChatEventArgs()
|
||||
{
|
||||
Client=sender,
|
||||
Message=msg,
|
||||
ClaimedSender=clamiedSender
|
||||
Client = sender,
|
||||
Message = msg,
|
||||
ClaimedSender = clamiedSender
|
||||
});
|
||||
}
|
||||
internal void InvokePlayerConnected(Client client)
|
||||
{ OnPlayerConnected?.Invoke(this,client); }
|
||||
{ OnPlayerConnected?.Invoke(this, client); }
|
||||
internal void InvokePlayerReady(Client client)
|
||||
{ OnPlayerReady?.Invoke(this, client); }
|
||||
internal void InvokePlayerDisconnected(Client client)
|
||||
{ OnPlayerDisconnected?.Invoke(this,client); }
|
||||
{ OnPlayerDisconnected?.Invoke(this, client); }
|
||||
|
||||
internal void InvokeCustomEventReceived(Packets.CustomEvent p, Client sender)
|
||||
{
|
||||
var args = new CustomEventReceivedArgs() { Hash=p.Hash, Args=p.Args, Client=sender };
|
||||
List<Action<CustomEventReceivedArgs>> handlers;
|
||||
if (CustomEventHandlers.TryGetValue(p.Hash, out handlers))
|
||||
var args = new CustomEventReceivedArgs() { Hash = p.Hash, Args = p.Args, Client = sender };
|
||||
if (CustomEventHandlers.TryGetValue(p.Hash, out List<Action<CustomEventReceivedArgs>> handlers))
|
||||
{
|
||||
handlers.ForEach((x) => { x.Invoke(args); });
|
||||
}
|
||||
@ -136,32 +134,32 @@ namespace RageCoop.Server.Scripting
|
||||
public class API
|
||||
{
|
||||
internal readonly Server Server;
|
||||
internal readonly Dictionary<string, Func<Stream>> RegisteredFiles=new Dictionary<string, Func<System.IO.Stream>>();
|
||||
internal readonly Dictionary<string, Func<Stream>> RegisteredFiles = new Dictionary<string, Func<System.IO.Stream>>();
|
||||
internal API(Server server)
|
||||
{
|
||||
Server=server;
|
||||
Events=new(server);
|
||||
Server.RequestHandlers.Add(PacketType.FileTransferRequest, (data,client) =>
|
||||
Server = server;
|
||||
Events = new(server);
|
||||
Server.RequestHandlers.Add(PacketType.FileTransferRequest, (data, client) =>
|
||||
{
|
||||
var p = new Packets.FileTransferRequest();
|
||||
p.Deserialize(data);
|
||||
var id=Server.NewFileID();
|
||||
if(RegisteredFiles.TryGetValue(p.Name,out var s))
|
||||
var id = Server.NewFileID();
|
||||
if (RegisteredFiles.TryGetValue(p.Name, out var s))
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
Server.SendFile(s(), p.Name, client,id);
|
||||
Server.SendFile(s(), p.Name, client, id);
|
||||
});
|
||||
return new Packets.FileTransferResponse()
|
||||
{
|
||||
ID=id,
|
||||
Response=FileResponse.Loaded
|
||||
ID = id,
|
||||
Response = FileResponse.Loaded
|
||||
};
|
||||
}
|
||||
return new Packets.FileTransferResponse()
|
||||
{
|
||||
ID=id,
|
||||
Response=FileResponse.LoadFailed
|
||||
ID = id,
|
||||
Response = FileResponse.LoadFailed
|
||||
};
|
||||
});
|
||||
}
|
||||
@ -204,9 +202,9 @@ namespace RageCoop.Server.Scripting
|
||||
/// <param name="username">The username which send this message (default = "Server")</param>
|
||||
/// <param name="raiseEvent">Weather to raise the <see cref="ServerEvents.OnChatMessage"/> event defined in <see cref="API.Events"/></param>
|
||||
/// <remarks>When <paramref name="raiseEvent"/> is unspecified and <paramref name="targets"/> is null or unspecified, <paramref name="raiseEvent"/> will be set to true</remarks>
|
||||
public void SendChatMessage(string message, List<Client> targets = null, string username = "Server",bool? raiseEvent=null)
|
||||
public void SendChatMessage(string message, List<Client> targets = null, string username = "Server", bool? raiseEvent = null)
|
||||
{
|
||||
raiseEvent ??= targets==null;
|
||||
raiseEvent ??= targets == null;
|
||||
try
|
||||
{
|
||||
if (Server.MainNetServer.ConnectionsCount != 0)
|
||||
@ -233,7 +231,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
/// <param name="name">name of this file</param>
|
||||
/// <param name="path">path to this file</param>
|
||||
public void RegisterSharedFile(string name,string path)
|
||||
public void RegisterSharedFile(string name, string path)
|
||||
{
|
||||
RegisteredFiles.Add(name, () => { return File.OpenRead(path); });
|
||||
}
|
||||
@ -300,7 +298,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// <param name="hash"></param>
|
||||
/// <param name="args"></param>
|
||||
/// /// <param name="clients">Clients to send, null for all clients</param>
|
||||
public void SendNativeCall(List<Client> clients , GTA.Native.Hash hash, params object[] args)
|
||||
public void SendNativeCall(List<Client> clients, GTA.Native.Hash hash, params object[] args)
|
||||
{
|
||||
var argsList = new List<object>(args);
|
||||
argsList.InsertRange(0, new object[] { (byte)TypeCode.Empty, (ulong)hash });
|
||||
@ -320,8 +318,8 @@ namespace RageCoop.Server.Scripting
|
||||
targets ??= new(Server.ClientsByNetHandle.Values);
|
||||
var p = new Packets.CustomEvent()
|
||||
{
|
||||
Args=args,
|
||||
Hash=eventHash
|
||||
Args = args,
|
||||
Hash = eventHash
|
||||
};
|
||||
foreach (var c in targets)
|
||||
{
|
||||
@ -339,10 +337,10 @@ namespace RageCoop.Server.Scripting
|
||||
{
|
||||
|
||||
targets ??= new(Server.ClientsByNetHandle.Values);
|
||||
var p = new Packets.CustomEvent(null,true)
|
||||
var p = new Packets.CustomEvent(null, true)
|
||||
{
|
||||
Args=args,
|
||||
Hash=eventHash
|
||||
Args = args,
|
||||
Hash = eventHash
|
||||
};
|
||||
foreach (var c in targets)
|
||||
{
|
||||
@ -354,12 +352,11 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
/// <param name="hash">An unique identifier of the event, you can hash your event name with <see cref="CustomEvents.Hash(string)"/></param>
|
||||
/// <param name="handler">An handler to be invoked when the event is received from the server.</param>
|
||||
public void RegisterCustomEventHandler(int hash,Action<CustomEventReceivedArgs> handler)
|
||||
public void RegisterCustomEventHandler(int hash, Action<CustomEventReceivedArgs> handler)
|
||||
{
|
||||
List<Action<CustomEventReceivedArgs>> handlers;
|
||||
lock (Events.CustomEventHandlers)
|
||||
{
|
||||
if (!Events.CustomEventHandlers.TryGetValue(hash,out handlers))
|
||||
if (!Events.CustomEventHandlers.TryGetValue(hash, out List<Action<CustomEventReceivedArgs>> handlers))
|
||||
{
|
||||
Events.CustomEventHandlers.Add(hash, handlers = new List<Action<CustomEventReceivedArgs>>());
|
||||
}
|
||||
@ -385,11 +382,11 @@ namespace RageCoop.Server.Scripting
|
||||
/// <returns>A <see langword="dynamic"/> object reprensenting the script, or <see langword="null"/> if not found.</returns>
|
||||
/// <remarks>Explicitly casting the return value to orginal type will case a exception to be thrown due to the dependency isolation mechanism in resource system.
|
||||
/// You shouldn't reference the target resource assemblies either, since it causes the referenced assembly to be loaded and started in your resource.</remarks>
|
||||
public dynamic FindScript(string scriptFullName,string resourceName=null)
|
||||
public dynamic FindScript(string scriptFullName, string resourceName = null)
|
||||
{
|
||||
if (resourceName==null)
|
||||
if (resourceName == null)
|
||||
{
|
||||
foreach(var res in LoadedResources.Values)
|
||||
foreach (var res in LoadedResources.Values)
|
||||
{
|
||||
if (res.Scripts.TryGetValue(scriptFullName, out var script))
|
||||
{
|
||||
@ -399,7 +396,7 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
else if (LoadedResources.TryGetValue(resourceName, out var res))
|
||||
{
|
||||
if(res.Scripts.TryGetValue(scriptFullName, out var script))
|
||||
if (res.Scripts.TryGetValue(scriptFullName, out var script))
|
||||
{
|
||||
return script;
|
||||
}
|
||||
@ -424,7 +421,8 @@ namespace RageCoop.Server.Scripting
|
||||
public Client Host
|
||||
{
|
||||
get => Server._hostClient;
|
||||
set {
|
||||
set
|
||||
{
|
||||
if (Server._hostClient != value)
|
||||
{
|
||||
Server._hostClient?.SendCustomEvent(CustomEvents.IsHost, false);
|
||||
@ -440,7 +438,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// <remarks>Accessing this property from script constructor is stronly discouraged since other scripts and resources might have yet been loaded.
|
||||
/// Accessing from <see cref="ServerScript.OnStart"/> is not recommended either. Although all script assemblies will have been loaded to memory and instantiated, <see cref="ServerScript.OnStart"/> invocation of other scripts are not guaranteed.
|
||||
/// </remarks>
|
||||
public Dictionary<string,ServerResource> LoadedResources
|
||||
public Dictionary<string, ServerResource> LoadedResources
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -1,17 +1,14 @@
|
||||
using System;
|
||||
using RageCoop.Core.Scripting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using RageCoop.Core.Scripting;
|
||||
using RageCoop.Core;
|
||||
|
||||
namespace RageCoop.Server.Scripting
|
||||
{
|
||||
internal class BaseScript:ServerScript
|
||||
internal class BaseScript : ServerScript
|
||||
{
|
||||
private readonly Server Server;
|
||||
public BaseScript(Server server) { Server=server; }
|
||||
public BaseScript(Server server) { Server = server; }
|
||||
public override void OnStart()
|
||||
{
|
||||
API.RegisterCustomEventHandler(CustomEvents.NativeResponse, NativeResponse);
|
||||
@ -31,7 +28,7 @@ namespace RageCoop.Server.Scripting
|
||||
|
||||
foreach (var c in API.GetAllClients().Values)
|
||||
{
|
||||
if (c==e.Client)
|
||||
if (c == e.Client)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -41,49 +38,49 @@ namespace RageCoop.Server.Scripting
|
||||
});
|
||||
API.RegisterCustomEventHandler(CustomEvents.OnPlayerDied, (e) =>
|
||||
{
|
||||
API.SendCustomEventQueued(API.GetAllClients().Values.Where(x=>x!=e.Client).ToList(),CustomEvents.OnPlayerDied,e.Client.Username);
|
||||
API.SendCustomEventQueued(API.GetAllClients().Values.Where(x => x != e.Client).ToList(), CustomEvents.OnPlayerDied, e.Client.Username);
|
||||
});
|
||||
API.Events.OnChatMessage+=(s,e) =>
|
||||
API.Events.OnChatMessage += (s, e) =>
|
||||
Server.Logger?.Info((e.Client?.Username ?? e.ClaimedSender ?? "Unknown") + ": " + e.Message);
|
||||
}
|
||||
public override void OnStop()
|
||||
{
|
||||
}
|
||||
public static void SetAutoRespawn(Client c,bool toggle)
|
||||
public static void SetAutoRespawn(Client c, bool toggle)
|
||||
{
|
||||
c.SendCustomEvent(CustomEvents.SetAutoRespawn, toggle );
|
||||
c.SendCustomEvent(CustomEvents.SetAutoRespawn, toggle);
|
||||
}
|
||||
public void SetNameTag(Client c, bool toggle)
|
||||
{
|
||||
foreach(var other in API.GetAllClients().Values)
|
||||
foreach (var other in API.GetAllClients().Values)
|
||||
{
|
||||
if (c==other) { continue; }
|
||||
other.SendCustomEvent(CustomEvents.SetDisplayNameTag,c.Player.ID, toggle);
|
||||
if (c == other) { continue; }
|
||||
other.SendCustomEvent(CustomEvents.SetDisplayNameTag, c.Player.ID, toggle);
|
||||
}
|
||||
}
|
||||
public void SendServerPropsTo(List<ServerProp> objects,List<Client> clients=null)
|
||||
public void SendServerPropsTo(List<ServerProp> objects, List<Client> clients = null)
|
||||
{
|
||||
foreach(var obj in objects)
|
||||
foreach (var obj in objects)
|
||||
{
|
||||
API.SendCustomEventQueued(clients, CustomEvents.ServerPropSync,obj.ID, obj.Model ,obj.Position,obj.Rotation );
|
||||
API.SendCustomEventQueued(clients, CustomEvents.ServerPropSync, obj.ID, obj.Model, obj.Position, obj.Rotation);
|
||||
}
|
||||
}
|
||||
public void SendServerBlipsTo(List<ServerBlip> objects, List<Client> clients = null)
|
||||
{
|
||||
foreach (var obj in objects)
|
||||
{
|
||||
API.SendCustomEventQueued(clients, CustomEvents.ServerBlipSync, obj.ID, (ushort)obj.Sprite, (byte)obj.Color, obj.Scale,obj.Position,obj.Rotation,obj.Name );
|
||||
API.SendCustomEventQueued(clients, CustomEvents.ServerBlipSync, obj.ID, (ushort)obj.Sprite, (byte)obj.Color, obj.Scale, obj.Position, obj.Rotation, obj.Name);
|
||||
}
|
||||
}
|
||||
void NativeResponse(CustomEventReceivedArgs e)
|
||||
|
||||
private void NativeResponse(CustomEventReceivedArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
int id = (int)e.Args[0];
|
||||
Action<object> callback;
|
||||
lock (e.Client.Callbacks)
|
||||
{
|
||||
if (e.Client.Callbacks.TryGetValue(id, out callback))
|
||||
if (e.Client.Callbacks.TryGetValue(id, out Action<object> callback))
|
||||
{
|
||||
callback(e.Args[1]);
|
||||
e.Client.Callbacks.Remove(id);
|
||||
|
@ -1,8 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net;
|
||||
|
||||
namespace RageCoop.Server.Scripting
|
||||
@ -97,10 +94,10 @@ namespace RageCoop.Server.Scripting
|
||||
/// <param name="reason"></param>
|
||||
public void Deny(string reason)
|
||||
{
|
||||
DenyReason=reason;
|
||||
Cancel=true;
|
||||
DenyReason = reason;
|
||||
Cancel = true;
|
||||
}
|
||||
internal string DenyReason { get; set; }
|
||||
internal bool Cancel { get; set; }=false;
|
||||
internal bool Cancel { get; set; } = false;
|
||||
}
|
||||
}
|
||||
|
@ -1,36 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using RageCoop.Core.Scripting;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using RageCoop.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using System.Reflection;
|
||||
using McMaster.NETCore.Plugins;
|
||||
using System.Threading.Tasks;
|
||||
namespace RageCoop.Server.Scripting
|
||||
{
|
||||
internal class Resources
|
||||
{
|
||||
public Dictionary<string,ServerResource> LoadedResources=new();
|
||||
public Dictionary<string, ServerResource> LoadedResources = new();
|
||||
private readonly Server Server;
|
||||
private readonly Logger Logger;
|
||||
public bool IsLoaded { get; private set; } = false;
|
||||
public Resources(Server server)
|
||||
{
|
||||
Server = server;
|
||||
Logger=server.Logger;
|
||||
Logger = server.Logger;
|
||||
}
|
||||
private Dictionary<string,Stream> ClientResources=new();
|
||||
private Dictionary<string,Stream> ResourceStreams=new();
|
||||
private readonly Dictionary<string, Stream> ClientResources = new();
|
||||
private readonly Dictionary<string, Stream> ResourceStreams = new();
|
||||
public void LoadAll()
|
||||
{
|
||||
// Packages
|
||||
{
|
||||
var path = Path.Combine("Resources", "Packages");
|
||||
Directory.CreateDirectory(path);
|
||||
foreach (var pkg in Directory.GetFiles(path,"*.respkg",SearchOption.AllDirectories))
|
||||
foreach (var pkg in Directory.GetFiles(path, "*.respkg", SearchOption.AllDirectories))
|
||||
{
|
||||
Logger?.Debug($"Adding resources from package \"{Path.GetFileNameWithoutExtension(pkg)}\"");
|
||||
var pkgZip = new ZipFile(pkg);
|
||||
@ -41,7 +36,7 @@ namespace RageCoop.Server.Scripting
|
||||
{
|
||||
var stream = pkgZip.GetInputStream(e).ToMemStream();
|
||||
ClientResources.Add(Path.GetFileNameWithoutExtension(e.Name), stream);
|
||||
Logger?.Debug("Resource added: "+ Path.GetFileNameWithoutExtension(e.Name));
|
||||
Logger?.Debug("Resource added: " + Path.GetFileNameWithoutExtension(e.Name));
|
||||
}
|
||||
else if (e.Name.StartsWith("Server") && e.Name.EndsWith(".res"))
|
||||
{
|
||||
@ -58,7 +53,7 @@ namespace RageCoop.Server.Scripting
|
||||
// Client
|
||||
{
|
||||
var path = Path.Combine("Resources", "Client");
|
||||
var tmpDir = Path.Combine("Resources", "Temp","Client");
|
||||
var tmpDir = Path.Combine("Resources", "Temp", "Client");
|
||||
Directory.CreateDirectory(path);
|
||||
if (Directory.Exists(tmpDir))
|
||||
{
|
||||
@ -66,13 +61,13 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
Directory.CreateDirectory(tmpDir);
|
||||
var resourceFolders = Directory.GetDirectories(path, "*", SearchOption.TopDirectoryOnly);
|
||||
if (resourceFolders.Length!=0)
|
||||
if (resourceFolders.Length != 0)
|
||||
{
|
||||
foreach (var resourceFolder in resourceFolders)
|
||||
{
|
||||
// Pack client side resource as a zip file
|
||||
Logger?.Info("Packing client-side resource: "+resourceFolder);
|
||||
var zipPath = Path.Combine(tmpDir, Path.GetFileName(resourceFolder))+".res";
|
||||
Logger?.Info("Packing client-side resource: " + resourceFolder);
|
||||
var zipPath = Path.Combine(tmpDir, Path.GetFileName(resourceFolder)) + ".res";
|
||||
try
|
||||
{
|
||||
using ZipFile zip = ZipFile.Create(zipPath);
|
||||
@ -98,11 +93,11 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
}
|
||||
var packed = Directory.GetFiles(path, "*.res", SearchOption.TopDirectoryOnly);
|
||||
if (packed.Length>0)
|
||||
if (packed.Length > 0)
|
||||
{
|
||||
foreach(var file in packed)
|
||||
foreach (var file in packed)
|
||||
{
|
||||
ClientResources.Add(Path.GetFileNameWithoutExtension(file),File.OpenRead(file));
|
||||
ClientResources.Add(Path.GetFileNameWithoutExtension(file), File.OpenRead(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -122,12 +117,12 @@ namespace RageCoop.Server.Scripting
|
||||
Logger?.Warning($"Resource \"{name}\" has already been loaded, ignoring...");
|
||||
continue;
|
||||
}
|
||||
if (name.ToLower()=="data") { continue; }
|
||||
if (name.ToLower() == "data") { continue; }
|
||||
Logger?.Info($"Loading resource: {name}");
|
||||
var r = ServerResource.LoadFrom(resource, dataFolder, Logger);
|
||||
LoadedResources.Add(r.Name, r);
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger?.Error($"Failed to load resource: {Path.GetFileName(resource)}");
|
||||
Logger?.Error(ex);
|
||||
@ -135,13 +130,13 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
foreach (var res in Directory.GetFiles(path, "*.res", SearchOption.TopDirectoryOnly))
|
||||
{
|
||||
if (!ResourceStreams.TryAdd(Path.GetFileNameWithoutExtension(res),File.OpenRead(res)))
|
||||
if (!ResourceStreams.TryAdd(Path.GetFileNameWithoutExtension(res), File.OpenRead(res)))
|
||||
{
|
||||
Logger?.Warning($"Resource \"{res}\" cannot be loaded, ignoring...");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
foreach(var res in ResourceStreams)
|
||||
foreach (var res in ResourceStreams)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -151,11 +146,11 @@ namespace RageCoop.Server.Scripting
|
||||
Logger?.Warning($"Resource \"{name}\" has already been loaded, ignoring...");
|
||||
continue;
|
||||
}
|
||||
Logger?.Info($"Loading resource: "+name);
|
||||
Logger?.Info($"Loading resource: " + name);
|
||||
var r = ServerResource.LoadFrom(res.Value, name, Path.Combine("Resources", "Temp", "Server"), dataFolder, Logger);
|
||||
LoadedResources.Add(r.Name, r);
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger?.Error($"Failed to load resource: {res.Key}");
|
||||
Logger?.Error(ex);
|
||||
@ -169,17 +164,17 @@ namespace RageCoop.Server.Scripting
|
||||
{
|
||||
foreach (ServerScript s in r.Scripts.Values)
|
||||
{
|
||||
s.API=Server.API;
|
||||
s.API = Server.API;
|
||||
try
|
||||
{
|
||||
Logger?.Debug("Starting script:"+s.CurrentFile.Name);
|
||||
Logger?.Debug("Starting script:" + s.CurrentFile.Name);
|
||||
s.OnStart();
|
||||
}
|
||||
catch (Exception ex) { Logger?.Error($"Failed to start resource: {r.Name}"); Logger?.Error(ex); }
|
||||
}
|
||||
}
|
||||
}
|
||||
IsLoaded=true;
|
||||
IsLoaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,7 +190,7 @@ namespace RageCoop.Server.Scripting
|
||||
{
|
||||
s.OnStop();
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger?.Error(ex);
|
||||
}
|
||||
@ -204,7 +199,7 @@ namespace RageCoop.Server.Scripting
|
||||
{
|
||||
d.Dispose();
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"Resource \"{d.Name}\" cannot be unloaded.");
|
||||
Logger.Error(ex);
|
||||
@ -212,16 +207,16 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
LoadedResources.Clear();
|
||||
}
|
||||
foreach(var s in ResourceStreams.Values)
|
||||
foreach (var s in ResourceStreams.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
s.Close();
|
||||
s.Dispose();
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger?.Error("[Resources.CloseStream]",ex);
|
||||
Logger?.Error("[Resources.CloseStream]", ex);
|
||||
}
|
||||
}
|
||||
foreach (var s in ClientResources.Values)
|
||||
@ -265,7 +260,7 @@ namespace RageCoop.Server.Scripting
|
||||
Logger?.Warning($"Client {client.Username} failed to load resource.");
|
||||
}
|
||||
}
|
||||
catch(Exception ex)
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Failed to send resource to client: " + client.Username, ex);
|
||||
client.Kick("Resource error!");
|
||||
|
@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GTA;
|
||||
using GTA.Math;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using GTA.Math;
|
||||
using GTA;
|
||||
|
||||
namespace RageCoop.Server.Scripting
|
||||
{
|
||||
@ -25,8 +22,8 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
internal ConcurrentDictionary<int, ServerPed> Peds { get; set; } = new();
|
||||
internal ConcurrentDictionary<int, ServerVehicle> Vehicles { get; set; } = new();
|
||||
internal ConcurrentDictionary<int,ServerProp> ServerProps { get; set; }=new();
|
||||
internal ConcurrentDictionary<int,ServerBlip> Blips { get; set; } = new();
|
||||
internal ConcurrentDictionary<int, ServerProp> ServerProps { get; set; } = new();
|
||||
internal ConcurrentDictionary<int, ServerBlip> Blips { get; set; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="ServerPed"/> by it's id
|
||||
@ -63,16 +60,16 @@ namespace RageCoop.Server.Scripting
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="rot"></param>
|
||||
/// <returns></returns>
|
||||
public ServerProp CreateProp(Model model,Vector3 pos,Vector3 rot)
|
||||
public ServerProp CreateProp(Model model, Vector3 pos, Vector3 rot)
|
||||
{
|
||||
int id = RequestNetworkID();
|
||||
ServerProp prop;
|
||||
ServerProps.TryAdd(id,prop=new ServerProp(Server)
|
||||
ServerProps.TryAdd(id, prop = new ServerProp(Server)
|
||||
{
|
||||
ID=id,
|
||||
Model=model,
|
||||
_pos=pos,
|
||||
_rot=rot
|
||||
ID = id,
|
||||
Model = model,
|
||||
_pos = pos,
|
||||
_rot = rot
|
||||
});
|
||||
prop.Update();
|
||||
return prop;
|
||||
@ -86,17 +83,17 @@ namespace RageCoop.Server.Scripting
|
||||
/// <param name="pos">position</param>
|
||||
/// <param name="heading">heading of this vehicle</param>
|
||||
/// <returns></returns>
|
||||
public ServerVehicle CreateVehicle(Client owner,Model model,Vector3 pos,float heading)
|
||||
public ServerVehicle CreateVehicle(Client owner, Model model, Vector3 pos, float heading)
|
||||
{
|
||||
if(owner == null) { throw new ArgumentNullException("Owner cannot be null"); }
|
||||
if (owner == null) { throw new ArgumentNullException("Owner cannot be null"); }
|
||||
ServerVehicle veh = new(Server)
|
||||
{
|
||||
Owner=owner,
|
||||
ID=RequestNetworkID(),
|
||||
Model=model,
|
||||
_pos= pos,
|
||||
Owner = owner,
|
||||
ID = RequestNetworkID(),
|
||||
Model = model,
|
||||
_pos = pos,
|
||||
};
|
||||
owner.SendCustomEventQueued(CustomEvents.CreateVehicle,veh.ID, model, pos, heading);
|
||||
owner.SendCustomEventQueued(CustomEvents.CreateVehicle, veh.ID, model, pos, heading);
|
||||
Vehicles.TryAdd(veh.ID, veh);
|
||||
return veh;
|
||||
}
|
||||
@ -107,15 +104,15 @@ namespace RageCoop.Server.Scripting
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="rotation"></param>
|
||||
/// <returns></returns>
|
||||
public ServerBlip CreateBlip(Vector3 pos,int rotation)
|
||||
public ServerBlip CreateBlip(Vector3 pos, int rotation)
|
||||
{
|
||||
var b = new ServerBlip(Server)
|
||||
{
|
||||
ID=RequestNetworkID(),
|
||||
Position=pos,
|
||||
Rotation=rotation
|
||||
ID = RequestNetworkID(),
|
||||
Position = pos,
|
||||
Rotation = rotation
|
||||
};
|
||||
Blips.TryAdd(b.ID,b);
|
||||
Blips.TryAdd(b.ID, b);
|
||||
b.Update();
|
||||
return b;
|
||||
}
|
||||
@ -147,21 +144,21 @@ namespace RageCoop.Server.Scripting
|
||||
/// <summary>
|
||||
/// Not thread safe
|
||||
/// </summary>
|
||||
internal void Update(Packets.PedSync p,Client sender)
|
||||
internal void Update(Packets.PedSync p, Client sender)
|
||||
{
|
||||
if(!Peds.TryGetValue(p.ID,out ServerPed ped))
|
||||
if (!Peds.TryGetValue(p.ID, out ServerPed ped))
|
||||
{
|
||||
Peds.TryAdd(p.ID,ped=new ServerPed(Server));
|
||||
ped.ID=p.ID;
|
||||
Peds.TryAdd(p.ID, ped = new ServerPed(Server));
|
||||
ped.ID = p.ID;
|
||||
}
|
||||
ped._pos = p.Position;
|
||||
ped.Owner=sender;
|
||||
ped.Health=p.Health;
|
||||
ped._rot=p.Rotation;
|
||||
ped.Owner = sender;
|
||||
ped.Health = p.Health;
|
||||
ped._rot = p.Rotation;
|
||||
ped._isInvincible = p.Flags.HasPedFlag(PedDataFlags.IsInvincible);
|
||||
if (p.Speed>=4 && Vehicles.TryGetValue(p.VehicleID,out var v))
|
||||
if (p.Speed >= 4 && Vehicles.TryGetValue(p.VehicleID, out var v))
|
||||
{
|
||||
ped.LastVehicle=v;
|
||||
ped.LastVehicle = v;
|
||||
}
|
||||
|
||||
if (ped.Owner != sender)
|
||||
@ -178,12 +175,12 @@ namespace RageCoop.Server.Scripting
|
||||
{
|
||||
if (!Vehicles.TryGetValue(p.ID, out ServerVehicle veh))
|
||||
{
|
||||
Vehicles.TryAdd(p.ID, veh=new ServerVehicle(Server));
|
||||
veh.ID=p.ID;
|
||||
Vehicles.TryAdd(p.ID, veh = new ServerVehicle(Server));
|
||||
veh.ID = p.ID;
|
||||
}
|
||||
veh._pos = p.Position+p.Velocity*sender.Latency;
|
||||
veh._quat=p.Quaternion;
|
||||
if(veh.Owner != sender)
|
||||
veh._pos = p.Position + p.Velocity * sender.Latency;
|
||||
veh._quat = p.Quaternion;
|
||||
if (veh.Owner != sender)
|
||||
{
|
||||
if (veh.Owner != null)
|
||||
{
|
||||
@ -199,14 +196,14 @@ namespace RageCoop.Server.Scripting
|
||||
|
||||
foreach (var pair in Peds)
|
||||
{
|
||||
if (pair.Value.Owner==left)
|
||||
if (pair.Value.Owner == left)
|
||||
{
|
||||
Server.QueueJob(()=>Peds.TryRemove(pair.Key,out _));
|
||||
Server.QueueJob(() => Peds.TryRemove(pair.Key, out _));
|
||||
}
|
||||
}
|
||||
foreach (var pair in Vehicles)
|
||||
{
|
||||
if (pair.Value.Owner==left)
|
||||
if (pair.Value.Owner == left)
|
||||
{
|
||||
Server.QueueJob(() => Vehicles.TryRemove(pair.Key, out _));
|
||||
}
|
||||
@ -238,7 +235,7 @@ namespace RageCoop.Server.Scripting
|
||||
{
|
||||
if (Peds.ContainsKey(ped.ID))
|
||||
{
|
||||
Peds[ped.ID]=ped;
|
||||
Peds[ped.ID] = ped;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -247,7 +244,7 @@ namespace RageCoop.Server.Scripting
|
||||
internal int RequestNetworkID()
|
||||
{
|
||||
int ID = 0;
|
||||
while ((ID==0)
|
||||
while ((ID == 0)
|
||||
|| ServerProps.ContainsKey(ID)
|
||||
|| Peds.ContainsKey(ID)
|
||||
|| Vehicles.ContainsKey(ID)
|
||||
|
@ -1,14 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GTA;
|
||||
using GTA.Native;
|
||||
using GTA;
|
||||
using GTA.Math;
|
||||
using GTA.Native;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RageCoop.Server.Scripting
|
||||
{
|
||||
@ -22,7 +19,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// Server that this object belongs to
|
||||
/// </summary>
|
||||
internal readonly Server Server;
|
||||
internal ServerObject(Server server) { Server=server; }
|
||||
internal ServerObject(Server server) { Server = server; }
|
||||
|
||||
/// <summary>
|
||||
/// Pass this as an argument in CustomEvent or NativeCall to convert this object to handle at client side.
|
||||
@ -71,7 +68,7 @@ namespace RageCoop.Server.Scripting
|
||||
public virtual Vector3 Position
|
||||
{
|
||||
get => _pos;
|
||||
set { _pos=value; Owner.SendNativeCall(Hash.SET_ENTITY_COORDS_NO_OFFSET, Handle, value.X, value.Y, value.Z,1, 1,1 ); }
|
||||
set { _pos = value; Owner.SendNativeCall(Hash.SET_ENTITY_COORDS_NO_OFFSET, Handle, value.X, value.Y, value.Z, 1, 1, 1); }
|
||||
}
|
||||
internal Vector3 _pos;
|
||||
|
||||
@ -81,7 +78,7 @@ namespace RageCoop.Server.Scripting
|
||||
public virtual Vector3 Rotation
|
||||
{
|
||||
get => _rot;
|
||||
set { _rot=value; Owner.SendNativeCall(Hash.SET_ENTITY_ROTATION, Handle, value.X, value.Y, value.Z ,2,1); }
|
||||
set { _rot = value; Owner.SendNativeCall(Hash.SET_ENTITY_ROTATION, Handle, value.X, value.Y, value.Z, 2, 1); }
|
||||
}
|
||||
internal Vector3 _rot;
|
||||
|
||||
@ -105,7 +102,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// <exception cref="InvalidOperationException"></exception>
|
||||
public virtual void Freeze(bool toggle)
|
||||
{
|
||||
if (GetTypeByte()==50)
|
||||
if (GetTypeByte() == 50)
|
||||
{
|
||||
throw new InvalidOperationException("Can't freeze or unfreeze static server object");
|
||||
}
|
||||
@ -128,7 +125,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public override void Delete()
|
||||
{
|
||||
Server.API.SendCustomEventQueued(null,CustomEvents.DeleteServerProp,ID);
|
||||
Server.API.SendCustomEventQueued(null, CustomEvents.DeleteServerProp, ID);
|
||||
Server.API.Entities.RemoveProp(ID);
|
||||
}
|
||||
|
||||
@ -138,7 +135,7 @@ namespace RageCoop.Server.Scripting
|
||||
public override Vector3 Position
|
||||
{
|
||||
get => _pos;
|
||||
set { _pos=value; Server.API.SendNativeCall(null, Hash.SET_ENTITY_COORDS_NO_OFFSET, Handle, value.X, value.Y, value.Z, 1, 1, 1); }
|
||||
set { _pos = value; Server.API.SendNativeCall(null, Hash.SET_ENTITY_COORDS_NO_OFFSET, Handle, value.X, value.Y, value.Z, 1, 1, 1); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -147,7 +144,7 @@ namespace RageCoop.Server.Scripting
|
||||
public override Vector3 Rotation
|
||||
{
|
||||
get => _rot;
|
||||
set { _rot=value; Server.API.SendNativeCall(null, Hash.SET_ENTITY_ROTATION, Handle, value.X, value.Y, value.Z, 2, 1); }
|
||||
set { _rot = value; Server.API.SendNativeCall(null, Hash.SET_ENTITY_ROTATION, Handle, value.X, value.Y, value.Z, 2, 1); }
|
||||
}
|
||||
|
||||
|
||||
@ -198,9 +195,10 @@ namespace RageCoop.Server.Scripting
|
||||
/// <summary>
|
||||
/// Get or set whether this ped is invincible
|
||||
/// </summary>
|
||||
public bool IsInvincible {
|
||||
public bool IsInvincible
|
||||
{
|
||||
get => _isInvincible;
|
||||
set => Owner.SendNativeCall(Hash.SET_ENTITY_INVINCIBLE,Handle,value);
|
||||
set => Owner.SendNativeCall(Hash.SET_ENTITY_INVINCIBLE, Handle, value);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
@ -216,7 +214,7 @@ namespace RageCoop.Server.Scripting
|
||||
public override Vector3 Rotation
|
||||
{
|
||||
get => _quat.ToEulerAngles().ToDegree();
|
||||
set { Owner.SendNativeCall(Hash.SET_ENTITY_ROTATION, Handle ,value.X, value.Y ,value.Z); }
|
||||
set { Owner.SendNativeCall(Hash.SET_ENTITY_ROTATION, Handle, value.X, value.Y, value.Z); }
|
||||
}
|
||||
|
||||
internal Quaternion _quat;
|
||||
@ -226,7 +224,7 @@ namespace RageCoop.Server.Scripting
|
||||
public Quaternion Quaternion
|
||||
{
|
||||
get => _quat;
|
||||
set { _quat = value ;Owner.SendNativeCall(Hash.SET_ENTITY_QUATERNION, Handle, value.X, value.Y, value.Z, value.W); }
|
||||
set { _quat = value; Owner.SendNativeCall(Hash.SET_ENTITY_QUATERNION, Handle, value.X, value.Y, value.Z, value.W); }
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,28 +261,30 @@ namespace RageCoop.Server.Scripting
|
||||
/// <summary>
|
||||
/// Color of this blip
|
||||
/// </summary>
|
||||
public BlipColor Color {
|
||||
public BlipColor Color
|
||||
{
|
||||
get => _color;
|
||||
set { _color=value; Update(); }
|
||||
set { _color = value; Update(); }
|
||||
}
|
||||
|
||||
internal BlipSprite _sprite=BlipSprite.Standard;
|
||||
internal BlipSprite _sprite = BlipSprite.Standard;
|
||||
/// <summary>
|
||||
/// Sprite of this blip
|
||||
/// </summary>
|
||||
public BlipSprite Sprite {
|
||||
public BlipSprite Sprite
|
||||
{
|
||||
get => _sprite;
|
||||
set { _sprite=value; Update();}
|
||||
set { _sprite = value; Update(); }
|
||||
}
|
||||
|
||||
internal float _scale =1;
|
||||
internal float _scale = 1;
|
||||
/// <summary>
|
||||
/// Scale of this blip
|
||||
/// </summary>
|
||||
public float Scale
|
||||
{
|
||||
get => _scale;
|
||||
set { _scale=value;Update(); }
|
||||
set { _scale = value; Update(); }
|
||||
}
|
||||
|
||||
internal Vector3 _pos = new();
|
||||
@ -294,7 +294,7 @@ namespace RageCoop.Server.Scripting
|
||||
public Vector3 Position
|
||||
{
|
||||
get => _pos;
|
||||
set { _pos=value; Update(); }
|
||||
set { _pos = value; Update(); }
|
||||
}
|
||||
|
||||
internal int _rot;
|
||||
@ -304,17 +304,17 @@ namespace RageCoop.Server.Scripting
|
||||
public int Rotation
|
||||
{
|
||||
get => _rot;
|
||||
set { _rot=value; Update(); }
|
||||
set { _rot = value; Update(); }
|
||||
}
|
||||
|
||||
internal string _name="Beeeeeee";
|
||||
internal string _name = "Beeeeeee";
|
||||
/// <summary>
|
||||
/// Name of this blip
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set { _name=value; Update(); }
|
||||
set { _name = value; Update(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -322,23 +322,23 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public void Delete()
|
||||
{
|
||||
Server.API.SendCustomEventQueued(null, CustomEvents.DeleteServerBlip,ID);
|
||||
Server.API.SendCustomEventQueued(null, CustomEvents.DeleteServerBlip, ID);
|
||||
Server.Entities.RemoveServerBlip(ID);
|
||||
}
|
||||
|
||||
|
||||
private bool _bouncing=false;
|
||||
private bool _bouncing = false;
|
||||
internal void Update()
|
||||
{
|
||||
// 5ms debounce
|
||||
if (!_bouncing)
|
||||
{
|
||||
_bouncing=true;
|
||||
_bouncing = true;
|
||||
Task.Run(() =>
|
||||
{
|
||||
Thread.Sleep(5);
|
||||
DoUpdate();
|
||||
_bouncing=false;
|
||||
_bouncing = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -359,7 +359,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// <summary>
|
||||
/// Get the <see cref="ServerPed"/> that this blip attached to.
|
||||
/// </summary>
|
||||
public ServerPed Ped { get;internal set; }
|
||||
public ServerPed Ped { get; internal set; }
|
||||
internal PedBlip(ServerPed ped)
|
||||
{
|
||||
Ped = ped;
|
||||
@ -373,17 +373,17 @@ namespace RageCoop.Server.Scripting
|
||||
public BlipColor Color
|
||||
{
|
||||
get => _color;
|
||||
set { _color=value; Update(); }
|
||||
set { _color = value; Update(); }
|
||||
}
|
||||
|
||||
internal BlipSprite _sprite=BlipSprite.Standard;
|
||||
internal BlipSprite _sprite = BlipSprite.Standard;
|
||||
/// <summary>
|
||||
/// Sprite of this blip
|
||||
/// </summary>
|
||||
public BlipSprite Sprite
|
||||
{
|
||||
get => _sprite;
|
||||
set { _sprite=value; Update(); }
|
||||
set { _sprite = value; Update(); }
|
||||
}
|
||||
|
||||
internal float _scale = 1;
|
||||
@ -393,7 +393,7 @@ namespace RageCoop.Server.Scripting
|
||||
public float Scale
|
||||
{
|
||||
get => _scale;
|
||||
set { _scale=value; Update(); }
|
||||
set { _scale = value; Update(); }
|
||||
}
|
||||
|
||||
private bool _bouncing = false;
|
||||
@ -402,18 +402,18 @@ namespace RageCoop.Server.Scripting
|
||||
// 5ms debounce
|
||||
if (!_bouncing)
|
||||
{
|
||||
_bouncing=true;
|
||||
_bouncing = true;
|
||||
Task.Run(() =>
|
||||
{
|
||||
Thread.Sleep(5);
|
||||
DoUpdate();
|
||||
_bouncing=false;
|
||||
_bouncing = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
private void DoUpdate()
|
||||
{
|
||||
Ped.Owner.SendCustomEventQueued(CustomEvents.UpdatePedBlip,Ped.Handle,(byte)Color,(ushort)Sprite,Scale);
|
||||
Ped.Owner.SendCustomEventQueued(CustomEvents.UpdatePedBlip, Ped.Handle, (byte)Color, (ushort)Sprite, Scale);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using RageCoop.Core;
|
||||
using System.Reflection;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using McMaster.NETCore.Plugins;
|
||||
using System.IO;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace RageCoop.Server.Scripting
|
||||
@ -23,7 +23,7 @@ namespace RageCoop.Server.Scripting
|
||||
var runtimeLibs = Path.Combine(resDir, "RuntimeLibs", CoreUtils.GetInvariantRID());
|
||||
if (Directory.Exists(runtimeLibs))
|
||||
{
|
||||
logger?.Debug("Applying runtime libraries from "+ CoreUtils.GetInvariantRID());
|
||||
logger?.Debug("Applying runtime libraries from " + CoreUtils.GetInvariantRID());
|
||||
CoreUtils.CopyFilesRecursively(new(runtimeLibs), new(resDir));
|
||||
}
|
||||
|
||||
@ -34,44 +34,44 @@ namespace RageCoop.Server.Scripting
|
||||
CoreUtils.CopyFilesRecursively(new(runtimeLibs), new(resDir));
|
||||
}
|
||||
|
||||
var conf = new PluginConfig(Path.GetFullPath(Path.Combine(resDir, Path.GetFileName(resDir)+".dll")))
|
||||
var conf = new PluginConfig(Path.GetFullPath(Path.Combine(resDir, Path.GetFileName(resDir) + ".dll")))
|
||||
{
|
||||
PreferSharedTypes = true,
|
||||
EnableHotReload=false,
|
||||
IsUnloadable=false,
|
||||
LoadInMemory=true,
|
||||
EnableHotReload = false,
|
||||
IsUnloadable = false,
|
||||
LoadInMemory = true,
|
||||
};
|
||||
ServerResource r = new(conf);
|
||||
r.Logger= logger;
|
||||
r.Name=Path.GetFileName(resDir);
|
||||
r.Logger = logger;
|
||||
r.Name = Path.GetFileName(resDir);
|
||||
if (!File.Exists(conf.MainAssemblyPath))
|
||||
{
|
||||
r.Dispose();
|
||||
throw new FileNotFoundException($"Main assembly for resource \"{r.Name}\" cannot be found.");
|
||||
}
|
||||
r.Scripts = new();
|
||||
r.DataFolder=Path.Combine(dataFolder, r.Name);
|
||||
r.Reloaded+=(s, e) => { r.Logger?.Info($"Resource: {r.Name} has been reloaded"); };
|
||||
r.DataFolder = Path.Combine(dataFolder, r.Name);
|
||||
r.Reloaded += (s, e) => { r.Logger?.Info($"Resource: {r.Name} has been reloaded"); };
|
||||
|
||||
Directory.CreateDirectory(r.DataFolder);
|
||||
foreach (var dir in Directory.GetDirectories(resDir, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
r.Files.Add(dir, new ResourceFile()
|
||||
{
|
||||
IsDirectory=true,
|
||||
Name=dir.Substring(resDir.Length+1).Replace('\\','/')
|
||||
});;
|
||||
IsDirectory = true,
|
||||
Name = dir.Substring(resDir.Length + 1).Replace('\\', '/')
|
||||
}); ;
|
||||
}
|
||||
var assemblies=new Dictionary<ResourceFile,Assembly>();
|
||||
var assemblies = new Dictionary<ResourceFile, Assembly>();
|
||||
foreach (var file in Directory.GetFiles(resDir, "*", SearchOption.AllDirectories))
|
||||
{
|
||||
if (Path.GetFileName(file).CanBeIgnored()) { try { File.Delete(file); } catch { } continue; }
|
||||
var relativeName = file.Substring(resDir.Length+1).Replace('\\', '/');
|
||||
var relativeName = file.Substring(resDir.Length + 1).Replace('\\', '/');
|
||||
var rfile = new ResourceFile()
|
||||
{
|
||||
GetStream=() => { return new FileStream(file, FileMode.Open, FileAccess.Read); },
|
||||
IsDirectory=false,
|
||||
Name=relativeName
|
||||
GetStream = () => { return new FileStream(file, FileMode.Open, FileAccess.Read); },
|
||||
IsDirectory = false,
|
||||
Name = relativeName
|
||||
};
|
||||
if (file.EndsWith(".dll") && !relativeName.Contains('/') && IsManagedAssembly(file))
|
||||
{
|
||||
@ -79,9 +79,9 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
r.Files.Add(relativeName, rfile);
|
||||
}
|
||||
foreach(var a in assemblies)
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
if(a.Key.Name.ToLower() == r.Name.ToLower()+".dll")
|
||||
if (a.Key.Name.ToLower() == r.Name.ToLower() + ".dll")
|
||||
{
|
||||
|
||||
try
|
||||
@ -100,12 +100,12 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
return r;
|
||||
}
|
||||
internal static ServerResource LoadFrom(Stream input,string name, string tmpDir, string dataFolder, Logger logger = null)
|
||||
internal static ServerResource LoadFrom(Stream input, string name, string tmpDir, string dataFolder, Logger logger = null)
|
||||
{
|
||||
tmpDir=Path.Combine(tmpDir, name);
|
||||
if (Directory.Exists(tmpDir)) { Directory.Delete(tmpDir,true); }
|
||||
tmpDir = Path.Combine(tmpDir, name);
|
||||
if (Directory.Exists(tmpDir)) { Directory.Delete(tmpDir, true); }
|
||||
Directory.CreateDirectory(tmpDir);
|
||||
new FastZip().ExtractZip(input, tmpDir, FastZip.Overwrite.Always,null,null,null,true,true);
|
||||
new FastZip().ExtractZip(input, tmpDir, FastZip.Overwrite.Always, null, null, null, true, true);
|
||||
return LoadFrom(tmpDir, dataFolder, logger);
|
||||
}
|
||||
/// <summary>
|
||||
@ -119,7 +119,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// <summary>
|
||||
/// Get all <see cref="ServerScript"/> instance in this resource
|
||||
/// </summary>
|
||||
public Dictionary<string,ServerScript> Scripts { get; internal set; } = new();
|
||||
public Dictionary<string, ServerScript> Scripts { get; internal set; } = new();
|
||||
/// <summary>
|
||||
/// Get all <see cref="ResourceFile"/> that can be used to acces files in this resource
|
||||
/// </summary>
|
||||
@ -145,8 +145,8 @@ namespace RageCoop.Server.Scripting
|
||||
// Invoke script constructor
|
||||
var script = constructor.Invoke(null) as ServerScript;
|
||||
script.CurrentResource = this;
|
||||
script.CurrentFile=rfile;
|
||||
Scripts.Add(script.GetType().FullName,script);
|
||||
script.CurrentFile = rfile;
|
||||
Scripts.Add(script.GetType().FullName, script);
|
||||
count++;
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -171,7 +171,7 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if(count != 0)
|
||||
if (count != 0)
|
||||
{
|
||||
Logger?.Info($"Loaded {count} script(s) in {rfile.Name}");
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using RageCoop.Core.Scripting;
|
||||
using RageCoop.Core.Scripting;
|
||||
using System;
|
||||
|
||||
namespace RageCoop.Server.Scripting
|
||||
{
|
||||
|
@ -1,12 +1,7 @@
|
||||
using System;
|
||||
using RageCoop.Core;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net;
|
||||
using System.IO;
|
||||
using RageCoop.Core;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
namespace RageCoop.Server
|
||||
{
|
||||
@ -15,10 +10,10 @@ namespace RageCoop.Server
|
||||
private readonly Logger Logger;
|
||||
public Security(Logger logger)
|
||||
{
|
||||
Logger= logger;
|
||||
Logger = logger;
|
||||
}
|
||||
public RSA RSA=RSA.Create(2048);
|
||||
private Dictionary<IPEndPoint, Aes> SecuredConnections = new Dictionary<IPEndPoint, Aes>();
|
||||
public RSA RSA = RSA.Create(2048);
|
||||
private readonly Dictionary<IPEndPoint, Aes> SecuredConnections = new Dictionary<IPEndPoint, Aes>();
|
||||
|
||||
public bool HasSecuredConnection(IPEndPoint target)
|
||||
{
|
||||
@ -27,7 +22,7 @@ namespace RageCoop.Server
|
||||
|
||||
public byte[] Encrypt(byte[] data, IPEndPoint target)
|
||||
{
|
||||
var ms=new MemoryStream();
|
||||
var ms = new MemoryStream();
|
||||
using (var cs = new CryptoStream(ms, SecuredConnections[target].CreateEncryptor(), CryptoStreamMode.Write))
|
||||
{
|
||||
cs.Write(data, 0, data.Length);
|
||||
@ -39,7 +34,7 @@ namespace RageCoop.Server
|
||||
return new CryptoStream(new MemoryStream(data), SecuredConnections[target].CreateDecryptor(), CryptoStreamMode.Read).ReadToEnd();
|
||||
}
|
||||
|
||||
public void AddConnection(IPEndPoint endpoint, byte[] cryptedKey,byte[] cryptedIV)
|
||||
public void AddConnection(IPEndPoint endpoint, byte[] cryptedKey, byte[] cryptedIV)
|
||||
{
|
||||
var key = RSA.Decrypt(cryptedKey, RSAEncryptionPadding.Pkcs1);
|
||||
var iv = RSA.Decrypt(cryptedIV, RSAEncryptionPadding.Pkcs1);
|
||||
@ -49,7 +44,7 @@ namespace RageCoop.Server
|
||||
conAes.IV = iv;
|
||||
if (!SecuredConnections.ContainsKey(endpoint))
|
||||
{
|
||||
SecuredConnections.Add(endpoint,conAes);
|
||||
SecuredConnections.Add(endpoint, conAes);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -68,7 +68,7 @@
|
||||
/// <summary>
|
||||
/// NPC data won't be sent to a player if their distance is greater than this value. -1 for unlimited.
|
||||
/// </summary>
|
||||
public float NpcStreamingDistance { get; set; } = 500 ;
|
||||
public float NpcStreamingDistance { get; set; } = 500;
|
||||
|
||||
/// <summary>
|
||||
/// Player's data won't be sent to another player if their distance is greater than this value. -1 for unlimited.
|
||||
@ -123,6 +123,6 @@
|
||||
/// <summary>
|
||||
/// Player that spawned entities more than this amount will be kicked if <see cref="KickSpamming"/> is enabled.
|
||||
/// </summary>
|
||||
public int SpamLimit { get;set; } = 100;
|
||||
public int SpamLimit { get; set; } = 100;
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using System.Linq;
|
||||
using Lidgren.Network;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Lidgren.Network;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace RageCoop.Server
|
||||
{
|
||||
static partial class Util
|
||||
internal static partial class Util
|
||||
{
|
||||
|
||||
public static string DownloadString(string url)
|
||||
@ -35,7 +35,7 @@ namespace RageCoop.Server
|
||||
return "";
|
||||
}
|
||||
}
|
||||
public static List<NetConnection> Exclude(this IEnumerable<NetConnection> connections,NetConnection toExclude)
|
||||
public static List<NetConnection> Exclude(this IEnumerable<NetConnection> connections, NetConnection toExclude)
|
||||
{
|
||||
return new(connections.Where(e => e != toExclude));
|
||||
}
|
||||
@ -89,7 +89,7 @@ namespace RageCoop.Server
|
||||
|
||||
public static T Next<T>(this T[] values)
|
||||
{
|
||||
return values[new Random().Next(values.Length-1)];
|
||||
return values[new Random().Next(values.Length - 1)];
|
||||
}
|
||||
|
||||
public static string GetFinalRedirect(string url)
|
||||
|
Reference in New Issue
Block a user