Compare commits
41 Commits
Author | SHA1 | Date | |
---|---|---|---|
e88e903096 | |||
99642fd40c | |||
2fbf06b504 | |||
13b771ec9f | |||
3b987f59e0 | |||
de96f29097 | |||
6136cbfc14 | |||
ed145aedd6 | |||
3f3b5fd2d0 | |||
9173e9a99e | |||
6e64c458df | |||
76f959abe9 | |||
f2e85d66ab | |||
e30ef1f4bd | |||
6e8f6e78f6 | |||
f28c83ccbd | |||
a83821b3d2 | |||
3b5436064e | |||
c4b321324e | |||
ba8d525ddf | |||
884e2f39f0 | |||
76c529f1d1 | |||
df0064bd38 | |||
f1fc96bbd7 | |||
23e9326f5f | |||
4621fb4987 | |||
6c82895fa7 | |||
84b040766f | |||
f44558cd3b | |||
accdbbcbc6 | |||
2d4107f35e | |||
bac53fd769 | |||
8f63fee5b5 | |||
8d0ad0b600 | |||
dc08c0c1f6 | |||
faaa856aa5 | |||
eab64f9254 | |||
6c936cb8f9 | |||
83a37f8556 | |||
bb4eacce26 | |||
d5b71db5d4 |
48
.github/workflows/build-test.yaml
vendored
Normal file
48
.github/workflows/build-test.yaml
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
name: Build test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*' # matches every branch that doesn't contain a '/'
|
||||
- '*/*' # matches every branch containing a single '/'
|
||||
- '**' # matches every branch
|
||||
- '!main' # excludes main
|
||||
- '!dev-nightly' # excludes nightly
|
||||
|
||||
pull_request:
|
||||
branches: [ "main", "dev-nightly" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
dotnet-version: ['6.0.x']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v2
|
||||
with:
|
||||
dotnet-version: ${{ matrix.dotnet-version }}
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
- name: Restore nuget packages
|
||||
run: nuget restore
|
||||
- name: Build client and installer
|
||||
run: dotnet build RageCoop.Client.Installer/RageCoop.Client.Installer.csproj --configuration Release -o bin/Release/Client/RageCoop
|
||||
- name: Build server win-x64
|
||||
run: dotnet build RageCoop.Server/RageCoop.Server.csproj -o bin/Release/Server
|
||||
- name: Upload server
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: RageCoop.Server
|
||||
path: bin/Release/Server
|
||||
- name: Upload Client
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: RageCoop.Client
|
||||
path: bin/Release/Client
|
||||
- uses: actions/checkout@v2
|
||||
|
4
.github/workflows/nightly-build.yaml
vendored
4
.github/workflows/nightly-build.yaml
vendored
@ -2,9 +2,7 @@ name: Nightly-build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "main" ]
|
||||
pull_request:
|
||||
branches: [ "main" ]
|
||||
branches: [ "dev-nightly" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
@ -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,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
|
||||
{
|
||||
@ -45,7 +35,8 @@ namespace RageCoop.Client.Installer
|
||||
};
|
||||
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");
|
||||
@ -86,10 +78,10 @@ namespace RageCoop.Client.Installer
|
||||
Environment.Exit(1);
|
||||
}
|
||||
var shvdnVer = GetVer(shvdnPath);
|
||||
if (shvdnVer<new Version(3,5,1))
|
||||
if (shvdnVer < new Version(3, 6, 0))
|
||||
{
|
||||
MessageBox.Show("Please update ScriptHookVDotNet to latest version!" +
|
||||
$"\nCurrent version is {shvdnVer}, 3.5.1 or higher is required");
|
||||
$"\nCurrent version is {shvdnVer}, 3.6.0 or higher is required");
|
||||
Environment.Exit(1);
|
||||
}
|
||||
if (File.Exists(lemonPath))
|
||||
@ -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");
|
||||
}
|
||||
|
@ -0,0 +1,72 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<AssemblyName>RageCoop.Client.Installer</AssemblyName>
|
||||
<IntermediateOutputPath>obj\Debug\</IntermediateOutputPath>
|
||||
<BaseIntermediateOutputPath>obj\</BaseIntermediateOutputPath>
|
||||
<MSBuildProjectExtensionsPath>M:\SandBox-Shared\repos\RAGECOOP\RAGECOOP-V\RageCoop.Client.Installer\obj\</MSBuildProjectExtensionsPath>
|
||||
<_TargetAssemblyProjectName>RageCoop.Client.Installer</_TargetAssemblyProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" />
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="bg.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\RageCoop.Client\RageCoop.Client.csproj" />
|
||||
<ProjectReference Include="..\RageCoop.Core\RageCoop.Core.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="Resource.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resource.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="Resource.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resource.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ReferencePath Include="C:\Users\Sardelka\.nuget\packages\sharpziplib\1.3.3\lib\net45\ICSharpCode.SharpZipLib.dll" />
|
||||
<ReferencePath Include="C:\Users\Sardelka\.nuget\packages\microsoft.extensions.objectpool\6.0.8\lib\net461\Microsoft.Extensions.ObjectPool.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\mscorlib.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\PresentationCore.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\PresentationFramework.dll" />
|
||||
<ReferencePath Include="M:\SandBox-Shared\repos\RAGECOOP\RAGECOOP-V\bin\Debug\Client\RageCoop.Client.dll" />
|
||||
<ReferencePath Include="M:\SandBox-Shared\repos\RAGECOOP\RAGECOOP-V\bin\Debug\Core\RageCoop.Core.dll" />
|
||||
<ReferencePath Include="C:\Users\Sardelka\.nuget\packages\system.buffers\4.5.1\ref\net45\System.Buffers.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Core.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Data.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Drawing.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.IO.Compression.FileSystem.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Numerics.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Runtime.Serialization.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Windows.Controls.Ribbon.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Windows.Forms.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Xaml.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Xml.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\System.Xml.Linq.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\UIAutomationClient.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\UIAutomationClientsideProviders.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\UIAutomationProvider.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\UIAutomationTypes.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\WindowsBase.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\WindowsFormsIntegration.dll" />
|
||||
<ReferencePath Include="C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.8\Facades\netstandard.dll" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="M:\SandBox-Shared\repos\RAGECOOP\RAGECOOP-V\RageCoop.Client.Installer\obj\Debug\net48\MainWindow.g.cs" />
|
||||
<Compile Include="M:\SandBox-Shared\repos\RAGECOOP\RAGECOOP-V\RageCoop.Client.Installer\obj\Debug\net48\App.g.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" />
|
||||
</Project>
|
@ -6,12 +6,11 @@ using RageCoop.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -39,7 +38,7 @@ namespace RageCoop.Client
|
||||
internal static ulong Ticked = 0;
|
||||
internal static Vector3 PlayerPosition;
|
||||
internal static Scripting.Resources Resources = null;
|
||||
private static List<Func<bool>> QueuedActions = new List<Func<bool>>();
|
||||
private static readonly List<Func<bool>> QueuedActions = new List<Func<bool>>();
|
||||
public static Worker Worker;
|
||||
|
||||
/// <summary>
|
||||
@ -47,9 +46,6 @@ namespace RageCoop.Client
|
||||
/// </summary>
|
||||
public Main()
|
||||
{
|
||||
#if DEBUG_HIGH_PING
|
||||
Networking.SimulatedLatency=0.3f;
|
||||
#endif
|
||||
Worker = new Worker("RageCoop.Client.Main.Worker", Logger);
|
||||
try
|
||||
{
|
||||
@ -100,7 +96,7 @@ namespace RageCoop.Client
|
||||
KeyDown += OnKeyDown;
|
||||
KeyDown += (s, e) => { Scripting.API.Events.InvokeKeyDown(s, e); };
|
||||
KeyUp += (s, e) => { Scripting.API.Events.InvokeKeyUp(s, e); };
|
||||
Aborted += (object sender, EventArgs e) => CleanUp();
|
||||
Aborted += (object sender, EventArgs e) => Disconnected("Abort");
|
||||
|
||||
Util.NativeMemory();
|
||||
Counter.Restart();
|
||||
@ -111,24 +107,9 @@ namespace RageCoop.Client
|
||||
private bool _lastDead;
|
||||
private void OnTick(object sender, EventArgs e)
|
||||
{
|
||||
/*
|
||||
unsafe
|
||||
{
|
||||
var stationName = Function.Call<string>(Hash.GET_RADIO_STATION_NAME, Game.RadioStation);
|
||||
|
||||
//_GET_CURRENT_RADIO_TRACK_NAME
|
||||
var currentTrack = Function.Call<int>((Hash)0x34D66BC058019CE0, stationName);
|
||||
Function.Call(Hash.SET_RADIO_TRACK, "RADIO_03_HIPHOP_NEW", "ARM1_RADIO_STARTS");
|
||||
return currentTrack;
|
||||
|
||||
var h1 = Function.Call<int>(Hash._GET_CURRENT_RADIO_STATION_HASH);
|
||||
return $"{h1},{h2},{s},{s1}";
|
||||
}
|
||||
*/
|
||||
P = Game.Player.Character;
|
||||
PlayerPosition = P.ReadPosition();
|
||||
FPS = Game.FPS;
|
||||
// World.DrawMarker(MarkerType.DebugSphere, PedExtensions.RaycastEverything(default), default, default, new Vector3(0.2f, 0.2f, 0.2f), Color.AliceBlue);
|
||||
if (Game.IsLoading)
|
||||
{
|
||||
return;
|
||||
@ -137,7 +118,6 @@ namespace RageCoop.Client
|
||||
{
|
||||
#if !NON_INTERACTIVE
|
||||
GTA.UI.Notification.Show(GTA.UI.NotificationIcon.AllPlayersConf, "RAGECOOP", "Welcome!", $"Press ~g~{Main.Settings.MenuKey}~s~ to open the menu.");
|
||||
WorldThread.Traffic(!Settings.DisableTraffic);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -161,7 +141,9 @@ namespace RageCoop.Client
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
#if DEBUG
|
||||
Main.Logger.Error(ex);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (Networking.ShowNetworkInfo)
|
||||
@ -309,15 +291,48 @@ namespace RageCoop.Client
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void CleanUp()
|
||||
internal static void Connected()
|
||||
{
|
||||
Memory.ApplyPatches();
|
||||
if (Settings.Voice && !Voice.WasInitialized())
|
||||
{
|
||||
Voice.Init();
|
||||
}
|
||||
QueueAction(() =>
|
||||
{
|
||||
MainChat.Clear();
|
||||
Voice.ClearAll();
|
||||
EntityPool.Cleanup();
|
||||
PlayerList.Cleanup();
|
||||
LocalPlayerID=default;
|
||||
WorldThread.Traffic(!Settings.DisableTraffic);
|
||||
Function.Call(Hash.SET_ENABLE_VEHICLE_SLIPSTREAMING, true);
|
||||
CoopMenu.ConnectedMenuSetting();
|
||||
MainChat.Init();
|
||||
GTA.UI.Notification.Show("~g~Connected!");
|
||||
});
|
||||
|
||||
Logger.Info(">> Connected <<");
|
||||
}
|
||||
public static void Disconnected(string reason)
|
||||
{
|
||||
|
||||
|
||||
Logger.Info($">> Disconnected << reason: {reason}");
|
||||
QueueAction(() =>
|
||||
{
|
||||
if (MainChat.Focused)
|
||||
{
|
||||
MainChat.Focused = false;
|
||||
}
|
||||
PlayerList.Cleanup();
|
||||
MainChat.Clear();
|
||||
EntityPool.Cleanup();
|
||||
WorldThread.Traffic(true);
|
||||
Function.Call(Hash.SET_ENABLE_VEHICLE_SLIPSTREAMING, false);
|
||||
CoopMenu.DisconnectedMenuSetting();
|
||||
GTA.UI.Notification.Show("~r~Disconnected: " + reason);
|
||||
LocalPlayerID = default;
|
||||
});
|
||||
Memory.RestorePatches();
|
||||
DownloadManager.Cleanup();
|
||||
Voice.ClearAll();
|
||||
Resources.Unload();
|
||||
}
|
||||
private static void DoQueuedActions()
|
||||
{
|
||||
@ -334,7 +349,9 @@ namespace RageCoop.Client
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
#if DEBUG
|
||||
Logger.Error(ex);
|
||||
#endif
|
||||
QueuedActions.Remove(action);
|
||||
}
|
||||
}
|
||||
@ -375,5 +392,6 @@ namespace RageCoop.Client
|
||||
QueueAction(a);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
using GTA;
|
||||
using GTA.Native;
|
||||
using LemonUI;
|
||||
using LemonUI.Menus;
|
||||
using LemonUI.Scaleform;
|
||||
@ -66,17 +67,18 @@ namespace RageCoop.Client.Menus
|
||||
|
||||
Menu.AddSubMenu(SettingsMenu.Menu);
|
||||
Menu.AddSubMenu(DevToolMenu.Menu);
|
||||
#if DEBUG
|
||||
Menu.AddSubMenu(DebugMenu.Menu);
|
||||
Menu.AddSubMenu(UpdateMenu.Menu);
|
||||
|
||||
#endif
|
||||
|
||||
MenuPool.Add(Menu);
|
||||
MenuPool.Add(SettingsMenu.Menu);
|
||||
MenuPool.Add(DevToolMenu.Menu);
|
||||
#if DEBUG
|
||||
MenuPool.Add(DebugMenu.Menu);
|
||||
MenuPool.Add(DebugMenu.DiagnosticMenu);
|
||||
#endif
|
||||
MenuPool.Add(ServersMenu.Menu);
|
||||
MenuPool.Add(UpdateMenu.Menu);
|
||||
MenuPool.Add(PopUp);
|
||||
|
||||
Menu.Add(_aboutItem);
|
||||
@ -96,6 +98,16 @@ namespace RageCoop.Client.Menus
|
||||
{
|
||||
Game.DisableAllControlsThisFrame();
|
||||
MenuPool.Process();
|
||||
|
||||
var scaleform = new Scaleform("instructional_buttons");
|
||||
scaleform.CallFunction("CLEAR_ALL");
|
||||
scaleform.CallFunction("TOGGLE_MOUSE_BUTTONS", 0);
|
||||
scaleform.CallFunction("CREATE_CONTAINER");
|
||||
|
||||
scaleform.CallFunction("SET_DATA_SLOT", 0, Function.Call<string>((Hash)0x0499D7B09FC9B407, 2, (int)Control.FrontendAccept, 0), "Continue");
|
||||
scaleform.CallFunction("SET_DATA_SLOT", 1, Function.Call<string>((Hash)0x0499D7B09FC9B407, 2, (int)Control.FrontendCancel, 0), "Cancel");
|
||||
scaleform.CallFunction("DRAW_INSTRUCTIONAL_BUTTONS", -1);
|
||||
scaleform.Render2D();
|
||||
if (Game.IsControlJustPressed(Control.FrontendAccept))
|
||||
{
|
||||
PopUp.Visible = false;
|
||||
@ -107,6 +119,8 @@ namespace RageCoop.Client.Menus
|
||||
return false;
|
||||
}
|
||||
Script.Yield();
|
||||
Game.DisableAllControlsThisFrame();
|
||||
|
||||
}
|
||||
}
|
||||
public static void UsernameActivated(object a, System.EventArgs b)
|
||||
|
@ -1,7 +1,8 @@
|
||||
using GTA;
|
||||
#if DEBUG
|
||||
using GTA;
|
||||
using LemonUI.Menus;
|
||||
using System.Drawing;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -56,3 +57,4 @@ namespace RageCoop.Client
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -12,9 +12,9 @@ namespace RageCoop.Client
|
||||
UseMouse = false,
|
||||
Alignment = Main.Settings.FlipMenu ? GTA.UI.Alignment.Right : GTA.UI.Alignment.Left
|
||||
};
|
||||
private static NativeCheckboxItem enableItem = new NativeCheckboxItem("Enable");
|
||||
private static readonly NativeCheckboxItem enableItem = new NativeCheckboxItem("Enable");
|
||||
|
||||
private static NativeCheckboxItem enableSecondaryItem = new NativeCheckboxItem("Secondary", "Enable if this vehicle have two muzzles");
|
||||
private static readonly NativeCheckboxItem enableSecondaryItem = new NativeCheckboxItem("Secondary", "Enable if this vehicle have two muzzles");
|
||||
public static NativeItem boneIndexItem = new NativeItem("Current bone index");
|
||||
public static NativeItem secondaryBoneIndexItem = new NativeItem("Secondary bone index");
|
||||
public static NativeItem clipboardItem = new NativeItem("Copy to clipboard");
|
||||
|
@ -1,12 +1,12 @@
|
||||
using LemonUI.Menus;
|
||||
using GTA.UI;
|
||||
using LemonUI.Menus;
|
||||
using Newtonsoft.Json;
|
||||
using RageCoop.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using RageCoop.Core;
|
||||
using GTA.UI;
|
||||
|
||||
namespace RageCoop.Client.Menus
|
||||
{
|
||||
|
@ -19,9 +19,9 @@ namespace RageCoop.Client.Menus
|
||||
private static readonly NativeCheckboxItem _disablePauseAlt = new NativeCheckboxItem("Disable Alternate Pause", "Don't freeze game time when Esc pressed", Main.Settings.DisableAlternatePause);
|
||||
private static readonly NativeCheckboxItem _disableVoice = new NativeCheckboxItem("Enable voice", "Check your GTA:V settings to find the right key on your keyboard for PushToTalk and talk to your friends", Main.Settings.Voice);
|
||||
|
||||
private static NativeItem _menuKey = new NativeItem("Menu Key", "The key to open menu", Main.Settings.MenuKey.ToString());
|
||||
private static NativeItem _passengerKey = new NativeItem("Passenger Key", "The key to enter a vehicle as passenger", Main.Settings.PassengerKey.ToString());
|
||||
private static NativeItem _vehicleSoftLimit = new NativeItem("Vehicle limit (soft)", "The game won't spawn more NPC traffic if the limit is exceeded. \n-1 for unlimited (not recommended).", Main.Settings.WorldVehicleSoftLimit.ToString());
|
||||
private static readonly NativeItem _menuKey = new NativeItem("Menu Key", "The key to open menu", Main.Settings.MenuKey.ToString());
|
||||
private static readonly NativeItem _passengerKey = new NativeItem("Passenger Key", "The key to enter a vehicle as passenger", Main.Settings.PassengerKey.ToString());
|
||||
private static readonly NativeItem _vehicleSoftLimit = new NativeItem("Vehicle limit (soft)", "The game won't spawn more NPC traffic if the limit is exceeded. \n-1 for unlimited (not recommended).", Main.Settings.WorldVehicleSoftLimit.ToString());
|
||||
|
||||
static SettingsMenu()
|
||||
{
|
||||
@ -53,7 +53,9 @@ namespace RageCoop.Client.Menus
|
||||
{
|
||||
Voice.Init();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
Voice.ClearAll();
|
||||
}
|
||||
|
||||
|
@ -1,105 +0,0 @@
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using LemonUI.Menus;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RageCoop.Client.Menus
|
||||
{
|
||||
internal class UpdateMenu
|
||||
{
|
||||
public static bool IsUpdating { get; private set; } = false;
|
||||
private static NativeItem _updatingItem = new NativeItem("Updating...");
|
||||
private static NativeItem _downloadItem = new NativeItem("Download", "Download and update to latest nightly");
|
||||
|
||||
private static string _downloadPath = Path.Combine(Main.Settings.DataDirectory, "RageCoop.Client.zip");
|
||||
public static NativeMenu Menu = new NativeMenu("Update", "Update", "Download and install latest nightly build from GitHub")
|
||||
{
|
||||
UseMouse = false,
|
||||
Alignment = Main.Settings.FlipMenu ? GTA.UI.Alignment.Right : GTA.UI.Alignment.Left
|
||||
};
|
||||
static UpdateMenu()
|
||||
{
|
||||
Menu.Banner.Color = Color.FromArgb(225, 0, 0, 0);
|
||||
Menu.Title.Color = Color.FromArgb(255, 165, 0);
|
||||
Menu.Opening+=Opening;
|
||||
_downloadItem.Activated+=StartUpdate;
|
||||
}
|
||||
|
||||
private static void StartUpdate(object sender, EventArgs e)
|
||||
{
|
||||
IsUpdating=true;
|
||||
Menu.Clear();
|
||||
Menu.Add(_updatingItem);
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(_downloadPath)) { File.Delete(_downloadPath); }
|
||||
WebClient client = new WebClient();
|
||||
|
||||
// TLS only
|
||||
ServicePointManager.Expect100Continue = true;
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13 | SecurityProtocolType.Tls12;
|
||||
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
|
||||
|
||||
client.DownloadProgressChanged += (s, e1) => { Main.QueueAction(() => { _updatingItem.AltTitle=$"{e1.ProgressPercentage}%"; }); };
|
||||
client.DownloadFileCompleted +=(s, e2) => { Install(); };
|
||||
client.DownloadFileAsync(new Uri("https://github.com/RAGECOOP/RAGECOOP-V/releases/download/nightly/RageCoop.Client.zip"), _downloadPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Main.Logger.Error(ex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void Install()
|
||||
{
|
||||
try
|
||||
{
|
||||
Main.QueueAction(() =>
|
||||
{
|
||||
_updatingItem.AltTitle="Installing...";
|
||||
});
|
||||
Directory.CreateDirectory(@"Scripts\RageCoop");
|
||||
foreach(var f in Directory.GetFiles(@"Scripts\RageCoop", "*.dll", SearchOption.AllDirectories))
|
||||
{
|
||||
try { File.Delete(f); }
|
||||
catch { }
|
||||
}
|
||||
new FastZip().ExtractZip(_downloadPath, "Scripts", FastZip.Overwrite.Always, null, null, null, true);
|
||||
try { File.Delete(_downloadPath); } catch { }
|
||||
try { File.Delete(Path.Combine("Scripts","RageCoop.Client.Installer.exe")); } catch { }
|
||||
Main.QueueAction(() =>
|
||||
{
|
||||
Util.Reload();
|
||||
IsUpdating=false;
|
||||
});
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Main.Logger.Error(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static void Opening(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
Menu.Clear();
|
||||
if (Networking.IsOnServer)
|
||||
{
|
||||
Menu.Add(new NativeItem("Disconnect from the server first"));
|
||||
}
|
||||
else if (IsUpdating)
|
||||
{
|
||||
Menu.Add(_updatingItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
Menu.Add(_downloadItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ namespace RageCoop.Client
|
||||
private bool CurrentFocused { get; set; }
|
||||
public bool Focused
|
||||
{
|
||||
get { return CurrentFocused; }
|
||||
get => CurrentFocused;
|
||||
set
|
||||
{
|
||||
if (value && Hidden)
|
||||
@ -35,7 +35,7 @@ namespace RageCoop.Client
|
||||
private bool CurrentHidden { get; set; }
|
||||
private bool Hidden
|
||||
{
|
||||
get { return CurrentHidden; }
|
||||
get => CurrentHidden;
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
|
@ -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();
|
||||
|
@ -1,12 +1,10 @@
|
||||
using System;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Timers;
|
||||
using RageCoop.Core;
|
||||
using Lidgren.Network;
|
||||
using System.Net;
|
||||
using System.Timers;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -29,7 +27,7 @@ namespace RageCoop.Client
|
||||
{
|
||||
if (p.InternalEndPoint != null && p.ExternalEndPoint != null && (p.Connection == null || p.Connection.Status == NetConnectionStatus.Disconnected))
|
||||
{
|
||||
Main.Logger.Trace($"Sending HolePunch message to {p.InternalEndPoint},{p.ExternalEndPoint}. {p.Username}:{p.PedID}");
|
||||
Main.Logger.Trace($"Sending HolePunch message to {p.InternalEndPoint},{p.ExternalEndPoint}. {p.Username}:{p.ID}");
|
||||
var msg = Networking.Peer.CreateMessage();
|
||||
new Packets.HolePunch
|
||||
{
|
||||
@ -69,7 +67,7 @@ namespace RageCoop.Client
|
||||
puncher.HolePunchStatus = (byte)(p.Status + 1);
|
||||
if (p.Status >= 3)
|
||||
{
|
||||
Main.Logger.Debug("HolePunch sucess: "+from+", "+puncher.PedID);
|
||||
Main.Logger.Debug("HolePunch sucess: " + from + ", " + puncher.ID);
|
||||
if (puncher.ConnectWhenPunched && (puncher.Connection == null || puncher.Connection.Status == NetConnectionStatus.Disconnected))
|
||||
{
|
||||
Main.Logger.Debug("Connecting to peer: " + from);
|
||||
|
@ -1,12 +1,12 @@
|
||||
using Lidgren.Network;
|
||||
using GTA.UI;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using GTA.UI;
|
||||
using System.Net;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -17,8 +17,8 @@ namespace RageCoop.Client
|
||||
public static bool ShowNetworkInfo = false;
|
||||
public static Security Security;
|
||||
public static NetConnection ServerConnection;
|
||||
private static readonly Dictionary<int, Action<PacketType, byte[]>> PendingResponses = new Dictionary<int, Action<PacketType, byte[]>>();
|
||||
internal static readonly Dictionary<PacketType, Func<byte[], Packet>> RequestHandlers = new Dictionary<PacketType, Func<byte[], Packet>>();
|
||||
private static readonly Dictionary<int, Action<PacketType, NetIncomingMessage>> PendingResponses = new Dictionary<int, Action<PacketType, NetIncomingMessage>>();
|
||||
internal static readonly Dictionary<PacketType, Func<NetIncomingMessage, Packet>> RequestHandlers = new Dictionary<PacketType, Func<NetIncomingMessage, Packet>>();
|
||||
internal static float SimulatedLatency = 0;
|
||||
public static bool IsConnecting { get; private set; }
|
||||
public static IPEndPoint _targetServerEP;
|
||||
@ -35,7 +35,8 @@ namespace RageCoop.Client
|
||||
{
|
||||
// ?
|
||||
}
|
||||
else if (IsConnecting) {
|
||||
else if (IsConnecting)
|
||||
{
|
||||
_publicKeyReceived.Set();
|
||||
IsConnecting = false;
|
||||
Notification.Show("Connection has been canceled");
|
||||
@ -52,13 +53,14 @@ namespace RageCoop.Client
|
||||
NetPeerConfiguration config = new NetPeerConfiguration("623c92c287cc392406e7aaaac1c0f3b0")
|
||||
{
|
||||
AutoFlushSendQueue = false,
|
||||
SimulatedMinimumLatency =SimulatedLatency,
|
||||
SimulatedRandomLatency=0,
|
||||
AcceptIncomingConnections = true,
|
||||
MaximumConnections = 32,
|
||||
PingInterval = 5
|
||||
};
|
||||
|
||||
#if DEBUG
|
||||
config.SimulatedMinimumLatency = SimulatedLatency;
|
||||
config.SimulatedRandomLatency = 0;
|
||||
#endif
|
||||
config.EnableMessageType(NetIncomingMessageType.UnconnectedData);
|
||||
config.EnableMessageType(NetIncomingMessageType.NatIntroductionSuccess);
|
||||
|
||||
@ -88,24 +90,33 @@ namespace RageCoop.Client
|
||||
try
|
||||
{
|
||||
_targetServerEP = CoreUtils.StringToEndPoint(address);
|
||||
|
||||
// Ensure static constructor invocation
|
||||
DownloadManager.Cleanup();
|
||||
Peer = new CoopPeer(config);
|
||||
Peer.OnMessageReceived += (s, m) =>
|
||||
{
|
||||
try { ProcessMessage(m); }
|
||||
catch (Exception ex) { Main.Logger.Error(ex); }
|
||||
catch (Exception ex)
|
||||
{
|
||||
#if DEBUG
|
||||
Main.Logger.Error(ex);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
Main.QueueAction(() => { Notification.Show($"~y~Trying to connect..."); });
|
||||
Menus.CoopMenu._serverConnectItem.Enabled = false;
|
||||
Security.Regen();
|
||||
if(publicKey==null){
|
||||
if (publicKey == null)
|
||||
{
|
||||
if (!GetServerPublicKey(ip[0], int.Parse(ip[1])))
|
||||
{
|
||||
Menus.CoopMenu._serverConnectItem.Enabled = true;
|
||||
throw new TimeoutException("Failed to retrive server's public key");
|
||||
}
|
||||
}
|
||||
else{
|
||||
else
|
||||
{
|
||||
Security.SetServerPublicKey(publicKey.Modulus, publicKey.Exponent);
|
||||
}
|
||||
|
||||
@ -141,7 +152,7 @@ namespace RageCoop.Client
|
||||
{
|
||||
var p = new Player
|
||||
{
|
||||
PedID = packet.PedID,
|
||||
ID = packet.PedID,
|
||||
Username = packet.Username,
|
||||
};
|
||||
PlayerList.SetPlayer(packet.PedID, packet.Username);
|
||||
@ -155,7 +166,8 @@ namespace RageCoop.Client
|
||||
var player = PlayerList.GetPlayer(packet.PedID);
|
||||
if (player == null) { return; }
|
||||
PlayerList.RemovePlayer(packet.PedID);
|
||||
Main.QueueAction(() => {
|
||||
Main.QueueAction(() =>
|
||||
{
|
||||
EntityPool.RemoveAllFromPlayer(packet.PedID);
|
||||
GTA.UI.Notification.Show($"~h~{player.Username}~h~ left.");
|
||||
});
|
||||
|
@ -3,9 +3,7 @@ using Lidgren.Network;
|
||||
using RageCoop.Client.Menus;
|
||||
using RageCoop.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using GTA.Native;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -15,7 +13,7 @@ namespace RageCoop.Client
|
||||
/// <summary>
|
||||
/// Reduce GC pressure by reusing frequently used packets
|
||||
/// </summary>
|
||||
static class ReceivedPackets
|
||||
private static class ReceivedPackets
|
||||
{
|
||||
public static Packets.PedSync PedPacket = new Packets.PedSync();
|
||||
public static Packets.VehicleSync VehicelPacket = new Packets.VehicleSync();
|
||||
@ -25,7 +23,7 @@ namespace RageCoop.Client
|
||||
/// <summary>
|
||||
/// Used to reslove entity handle in a <see cref="Packets.CustomEvent"/>
|
||||
/// </summary>
|
||||
private static readonly Func<byte, BitReader, object> _resolveHandle = (t, reader) =>
|
||||
private static readonly Func<byte, NetIncomingMessage, object> _resolveHandle = (t, reader) =>
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
@ -42,10 +40,11 @@ namespace RageCoop.Client
|
||||
}
|
||||
};
|
||||
private static readonly AutoResetEvent _publicKeyReceived = new AutoResetEvent(false);
|
||||
private static bool _recycle;
|
||||
public static void ProcessMessage(NetIncomingMessage message)
|
||||
{
|
||||
if (message == null) { return; }
|
||||
|
||||
_recycle = true;
|
||||
switch (message.MessageType)
|
||||
{
|
||||
case NetIncomingMessageType.StatusChanged:
|
||||
@ -62,32 +61,18 @@ namespace RageCoop.Client
|
||||
case NetConnectionStatus.Connected:
|
||||
if (message.SenderConnection == ServerConnection)
|
||||
{
|
||||
Memory.ApplyPatches();
|
||||
var response = message.SenderConnection.RemoteHailMessage;
|
||||
if ((PacketType)response.ReadByte() != PacketType.HandshakeSuccess)
|
||||
{
|
||||
throw new Exception("Invalid handshake response!");
|
||||
}
|
||||
var p = new Packets.HandshakeSuccess();
|
||||
p.Deserialize(response.ReadBytes(response.ReadInt32()));
|
||||
p.Deserialize(response);
|
||||
foreach (var player in p.Players)
|
||||
{
|
||||
PlayerList.SetPlayer(player.ID, player.Username);
|
||||
}
|
||||
Main.QueueAction(() =>
|
||||
{
|
||||
WorldThread.Traffic(!Main.Settings.DisableTraffic);
|
||||
Function.Call(Hash.SET_ENABLE_VEHICLE_SLIPSTREAMING, true);
|
||||
CoopMenu.ConnectedMenuSetting();
|
||||
Main.MainChat.Init();
|
||||
if (Main.Settings.Voice && !Voice.WasInitialized())
|
||||
{
|
||||
Voice.Init();
|
||||
}
|
||||
GTA.UI.Notification.Show("~g~Connected!");
|
||||
});
|
||||
|
||||
Main.Logger.Info(">> Connected <<");
|
||||
Main.Connected();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -110,19 +95,7 @@ namespace RageCoop.Client
|
||||
case NetConnectionStatus.Disconnected:
|
||||
if (message.SenderConnection == ServerConnection)
|
||||
{
|
||||
Memory.RestorePatches();
|
||||
DownloadManager.Cleanup();
|
||||
|
||||
if (Main.MainChat.Focused)
|
||||
{
|
||||
Main.MainChat.Focused = false;
|
||||
}
|
||||
|
||||
Main.QueueAction(() => Main.CleanUp());
|
||||
CoopMenu.DisconnectedMenuSetting();
|
||||
Main.Logger.Info($">> Disconnected << reason: {reason}");
|
||||
Main.QueueAction(() => GTA.UI.Notification.Show("~r~Disconnected: " + reason));
|
||||
Main.Resources.Unload();
|
||||
Main.Disconnected(reason);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -142,7 +115,7 @@ namespace RageCoop.Client
|
||||
int id = message.ReadInt32();
|
||||
if (PendingResponses.TryGetValue(id, out var callback))
|
||||
{
|
||||
callback((PacketType)message.ReadByte(), message.ReadBytes(message.ReadInt32()));
|
||||
callback((PacketType)message.ReadByte(), message);
|
||||
PendingResponses.Remove(id);
|
||||
}
|
||||
break;
|
||||
@ -151,57 +124,59 @@ namespace RageCoop.Client
|
||||
{
|
||||
int id = message.ReadInt32();
|
||||
var realType = (PacketType)message.ReadByte();
|
||||
int len = message.ReadInt32();
|
||||
if (RequestHandlers.TryGetValue(realType, out var handler))
|
||||
{
|
||||
var response = Peer.CreateMessage();
|
||||
response.Write((byte)PacketType.Response);
|
||||
response.Write(id);
|
||||
handler(message.ReadBytes(len)).Pack(response);
|
||||
handler(message).Pack(response);
|
||||
Peer.SendMessage(response, ServerConnection, NetDeliveryMethod.ReliableOrdered, message.SequenceChannel);
|
||||
Peer.FlushSendQueue();
|
||||
}
|
||||
else
|
||||
{
|
||||
Main.Logger.Debug("Did not find a request handler of type: " + realType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
byte[] data = message.ReadBytes(message.ReadInt32());
|
||||
|
||||
HandlePacket(packetType, data,message.SenderConnection);
|
||||
HandlePacket(packetType, message, message.SenderConnection, ref _recycle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
#if DEBUG
|
||||
Main.QueueAction(() =>
|
||||
{
|
||||
GTA.UI.Notification.Show("~r~~h~Packet Error");
|
||||
GTA.UI.Notification.Show($"~r~~h~Packet Error {ex.Message}");
|
||||
return true;
|
||||
});
|
||||
Main.Logger.Error($"[{packetType}] {ex.Message}");
|
||||
Main.Logger.Error(ex);
|
||||
Peer.Shutdown($"Packet Error [{packetType}]");
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NetIncomingMessageType.UnconnectedData:
|
||||
{
|
||||
var packetType = (PacketType)message.ReadByte();
|
||||
int len = message.ReadInt32();
|
||||
byte[] data = message.ReadBytes(len);
|
||||
switch (packetType)
|
||||
{
|
||||
|
||||
case PacketType.HolePunch:
|
||||
{
|
||||
HolePunch.Punched(data.GetPacket<Packets.HolePunch>(), message.SenderEndPoint);
|
||||
HolePunch.Punched(message.GetPacket<Packets.HolePunch>(), message.SenderEndPoint);
|
||||
break;
|
||||
}
|
||||
case PacketType.PublicKeyResponse:
|
||||
{
|
||||
if (message.SenderEndPoint.ToString() != _targetServerEP.ToString() || !IsConnecting) { break; }
|
||||
var packet = data.GetPacket<Packets.PublicKeyResponse>();
|
||||
var packet = message.GetPacket<Packets.PublicKeyResponse>();
|
||||
Security.SetServerPublicKey(packet.Modulus, packet.Exponent);
|
||||
_publicKeyReceived.Set();
|
||||
break;
|
||||
@ -218,41 +193,42 @@ namespace RageCoop.Client
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (_recycle)
|
||||
{
|
||||
Peer.Recycle(message);
|
||||
}
|
||||
private static void HandlePacket(PacketType packetType, byte[] data, NetConnection senderConnection)
|
||||
}
|
||||
private static void HandlePacket(PacketType packetType, NetIncomingMessage msg, NetConnection senderConnection, ref bool recycle)
|
||||
{
|
||||
|
||||
switch (packetType)
|
||||
{
|
||||
case PacketType.HolePunchInit:
|
||||
HolePunch.Add(data.GetPacket<Packets.HolePunchInit>());
|
||||
HolePunch.Add(msg.GetPacket<Packets.HolePunchInit>());
|
||||
break;
|
||||
|
||||
case PacketType.PlayerConnect:
|
||||
PlayerConnect(data.GetPacket<Packets.PlayerConnect>());
|
||||
PlayerConnect(msg.GetPacket<Packets.PlayerConnect>());
|
||||
break;
|
||||
|
||||
case PacketType.PlayerDisconnect:
|
||||
PlayerDisconnect(data.GetPacket<Packets.PlayerDisconnect>());
|
||||
PlayerDisconnect(msg.GetPacket<Packets.PlayerDisconnect>());
|
||||
break;
|
||||
|
||||
case PacketType.PlayerInfoUpdate:
|
||||
PlayerList.UpdatePlayer(data.GetPacket<Packets.PlayerInfoUpdate>());
|
||||
PlayerList.UpdatePlayer(msg.GetPacket<Packets.PlayerInfoUpdate>());
|
||||
break;
|
||||
|
||||
case PacketType.VehicleSync:
|
||||
ReceivedPackets.VehicelPacket.Deserialize(data);
|
||||
ReceivedPackets.VehicelPacket.Deserialize(msg);
|
||||
VehicleSync(ReceivedPackets.VehicelPacket);
|
||||
break;
|
||||
|
||||
case PacketType.PedSync:
|
||||
ReceivedPackets.PedPacket.Deserialize(data);
|
||||
ReceivedPackets.PedPacket.Deserialize(msg);
|
||||
PedSync(ReceivedPackets.PedPacket);
|
||||
break;
|
||||
case PacketType.ProjectileSync:
|
||||
ReceivedPackets.ProjectilePacket.Deserialize(data);
|
||||
ReceivedPackets.ProjectilePacket.Deserialize(msg);
|
||||
ProjectileSync(ReceivedPackets.ProjectilePacket);
|
||||
break;
|
||||
|
||||
@ -260,7 +236,7 @@ namespace RageCoop.Client
|
||||
{
|
||||
|
||||
Packets.ChatMessage packet = new Packets.ChatMessage((b) => Security.Decrypt(b));
|
||||
packet.Deserialize(data);
|
||||
packet.Deserialize(msg);
|
||||
|
||||
Main.QueueAction(() => { Main.MainChat.AddMessage(packet.Username, packet.Message); return true; });
|
||||
}
|
||||
@ -271,7 +247,7 @@ namespace RageCoop.Client
|
||||
if (Main.Settings.Voice)
|
||||
{
|
||||
Packets.Voice packet = new Packets.Voice();
|
||||
packet.Deserialize(data);
|
||||
packet.Deserialize(msg);
|
||||
|
||||
|
||||
SyncedPed player = EntityPool.GetPedByID(packet.ID);
|
||||
@ -286,18 +262,20 @@ namespace RageCoop.Client
|
||||
case PacketType.CustomEvent:
|
||||
{
|
||||
Packets.CustomEvent packet = new Packets.CustomEvent(_resolveHandle);
|
||||
packet.Deserialize(data);
|
||||
packet.Deserialize(msg);
|
||||
Scripting.API.Events.InvokeCustomEventReceived(packet);
|
||||
}
|
||||
break;
|
||||
|
||||
case PacketType.CustomEventQueued:
|
||||
{
|
||||
recycle = false;
|
||||
Packets.CustomEvent packet = new Packets.CustomEvent(_resolveHandle);
|
||||
Main.QueueAction(() =>
|
||||
{
|
||||
packet.Deserialize(data);
|
||||
packet.Deserialize(msg);
|
||||
Scripting.API.Events.InvokeCustomEventReceived(packet);
|
||||
Peer.Recycle(msg);
|
||||
});
|
||||
}
|
||||
break;
|
||||
@ -305,7 +283,7 @@ namespace RageCoop.Client
|
||||
case PacketType.FileTransferChunk:
|
||||
{
|
||||
Packets.FileTransferChunk packet = new Packets.FileTransferChunk();
|
||||
packet.Deserialize(data);
|
||||
packet.Deserialize(msg);
|
||||
DownloadManager.Write(packet.ID, packet.FileChunk);
|
||||
}
|
||||
break;
|
||||
@ -313,8 +291,9 @@ namespace RageCoop.Client
|
||||
default:
|
||||
if (packetType.IsSyncEvent())
|
||||
{
|
||||
recycle = false;
|
||||
// Dispatch to script thread
|
||||
Main.QueueAction(() => { SyncEvents.HandleEvent(packetType, data); return true; });
|
||||
Main.QueueAction(() => { SyncEvents.HandleEvent(packetType, msg); Peer.Recycle(msg); return true; });
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -424,6 +403,7 @@ namespace RageCoop.Client
|
||||
p.Shooter = packet.Flags.HasProjDataFlag(ProjectileDataFlags.IsShotByVehicle) ?
|
||||
(SyncedEntity)EntityPool.GetVehicleByID(packet.ShooterID) : EntityPool.GetPedByID(packet.ShooterID);
|
||||
p.LastSynced = Main.Ticked;
|
||||
p.LastSyncedStopWatch.Restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ namespace RageCoop.Client
|
||||
/// <summary>
|
||||
/// Reduce GC pressure by reusing frequently used packets
|
||||
/// </summary>
|
||||
static class SendPackets
|
||||
private static class SendPackets
|
||||
{
|
||||
public static Packets.PedSync PedPacket = new Packets.PedSync();
|
||||
public static Packets.VehicleSync VehicelPacket = new Packets.VehicleSync();
|
||||
|
@ -1,11 +1,11 @@
|
||||
using GTA;
|
||||
using GTA.Math;
|
||||
using GTA.Native;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Core;
|
||||
using System.Collections.Generic;
|
||||
using Lidgren.Network;
|
||||
using System.Net;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -63,16 +63,15 @@ 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.PedID=id;
|
||||
p.ID = id;
|
||||
p._latencyToServer = latency;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = new Player { PedID=id, Username=username, _latencyToServer=latency };
|
||||
p = new Player { ID = id, Username = username, _latencyToServer = latency };
|
||||
Players.Add(id, p);
|
||||
}
|
||||
}
|
||||
@ -90,7 +89,7 @@ namespace RageCoop.Client
|
||||
{
|
||||
p.FakeBlip = World.CreateBlip(p.Position);
|
||||
}
|
||||
if (EntityPool.PedExists(p.PedID))
|
||||
if (EntityPool.PedExists(p.ID))
|
||||
{
|
||||
p.FakeBlip.DisplayType = BlipDisplayType.NoDisplay;
|
||||
}
|
||||
@ -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)
|
||||
@ -139,32 +137,32 @@ namespace RageCoop.Client
|
||||
}
|
||||
}
|
||||
|
||||
internal class Player
|
||||
public class Player
|
||||
{
|
||||
public byte HolePunchStatus { get; set; } = 1;
|
||||
public bool IsHost;
|
||||
public byte HolePunchStatus { get; internal set; } = 1;
|
||||
public bool IsHost { get; internal set; }
|
||||
public string Username { get; internal set; }
|
||||
/// <summary>
|
||||
/// Universal character ID.
|
||||
/// Universal ped ID.
|
||||
/// </summary>
|
||||
public int PedID
|
||||
public int ID
|
||||
{
|
||||
get; internal set;
|
||||
}
|
||||
public IPEndPoint InternalEndPoint { get; set; }
|
||||
public IPEndPoint ExternalEndPoint { get; set; }
|
||||
public bool ConnectWhenPunched { get; set; }
|
||||
public Blip FakeBlip { get; set; }
|
||||
public Vector3 Position { get; set; }
|
||||
public SyncedPed Character { get; set; }
|
||||
public IPEndPoint InternalEndPoint { get; internal set; }
|
||||
public IPEndPoint ExternalEndPoint { get; internal set; }
|
||||
internal bool ConnectWhenPunched { get; set; }
|
||||
public Blip FakeBlip { get; internal set; }
|
||||
public Vector3 Position { get; internal set; }
|
||||
public SyncedPed Character { get; internal set; }
|
||||
/// <summary>
|
||||
/// Player round-trip time in seconds, will be the latency to server if not using P2P connection.
|
||||
/// Player round-trip time in seconds, will be the rtt to server if not using P2P connection.
|
||||
/// </summary>
|
||||
public float Ping => Main.LocalPlayerID==PedID ? Networking.Latency*2 : (HasDirectConnection ? Connection.AverageRoundtripTime : _latencyToServer*2);
|
||||
public float Ping => Main.LocalPlayerID == ID ? Networking.Latency * 2 : (HasDirectConnection ? Connection.AverageRoundtripTime : _latencyToServer * 2);
|
||||
public float PacketTravelTime => HasDirectConnection ? Connection.AverageRoundtripTime / 2 : Networking.Latency + _latencyToServer;
|
||||
public float _latencyToServer = 0;
|
||||
internal float _latencyToServer = 0;
|
||||
public bool DisplayNameTag { get; set; } = true;
|
||||
public NetConnection Connection { get; set; }
|
||||
public NetConnection Connection { get; internal set; }
|
||||
public bool HasDirectConnection => Connection?.Status == NetConnectionStatus.Connected;
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ using System.Resources;
|
||||
|
||||
|
||||
// Version informationr(
|
||||
[assembly: AssemblyVersion("1.5.3.124")]
|
||||
[assembly: AssemblyFileVersion("1.5.3.124")]
|
||||
[assembly: AssemblyVersion("1.5.4.4")]
|
||||
[assembly: AssemblyFileVersion("1.5.4.4")]
|
||||
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
<OutPutPath>..\bin\Debug\Client</OutPutPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DefineConstants>DEBUG</DefineConstants>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<OutPutPath>..\bin\Release\Client</OutPutPath>
|
||||
@ -35,7 +36,6 @@
|
||||
<Compile Include="Menus\Sub\DevToolMenu.cs" />
|
||||
<Compile Include="Menus\Sub\ServersMenu.cs" />
|
||||
<Compile Include="Menus\Sub\SettingsMenu.cs" />
|
||||
<Compile Include="Menus\Sub\UpdateMenu.cs" />
|
||||
<Compile Include="Networking\Chat.cs" />
|
||||
<Compile Include="Networking\DownloadManager.cs" />
|
||||
<Compile Include="Networking\HolePunch.cs" />
|
||||
@ -55,6 +55,7 @@
|
||||
<Compile Include="Scripting\Resources.cs" />
|
||||
<Compile Include="Security.cs" />
|
||||
<Compile Include="Settings.cs" />
|
||||
<Compile Include="Sync\Entities\Ped\SyncedPed.Members.cs" />
|
||||
<Compile Include="Sync\Entities\Ped\SyncedPed.Animations.cs" />
|
||||
<Compile Include="Sync\Entities\SyncedEntity.cs" />
|
||||
<Compile Include="Sync\Entities\Ped\SyncedPed.cs" />
|
||||
@ -65,6 +66,7 @@
|
||||
<Compile Include="Sync\EntityPool.cs" />
|
||||
<Compile Include="Sync\SyncEvents.cs" />
|
||||
<Compile Include="Sync\Voice.cs" />
|
||||
<Compile Include="Util\AddOnDataProvider.cs" />
|
||||
<Compile Include="Util\Memory.cs" />
|
||||
<Compile Include="Util\NativeCaller.cs" />
|
||||
<Compile Include="Util\PedConfigFlags.cs" />
|
||||
|
@ -1,5 +1,6 @@
|
||||
#undef DEBUG
|
||||
using GTA;
|
||||
using Newtonsoft.Json;
|
||||
using RageCoop.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -39,7 +40,7 @@ namespace RageCoop.Client.Scripting
|
||||
/// </summary>
|
||||
public static string Username
|
||||
{
|
||||
get { return Main.Settings.Username; }
|
||||
get => Main.Settings.Username;
|
||||
set
|
||||
{
|
||||
if (Networking.IsOnServer || string.IsNullOrEmpty(value))
|
||||
@ -145,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); });
|
||||
}
|
||||
@ -160,65 +160,48 @@ namespace RageCoop.Client.Scripting
|
||||
/// Get the local player's ID
|
||||
/// </summary>
|
||||
/// <returns>PlayerID</returns>
|
||||
public static int LocalPlayerID
|
||||
{
|
||||
get { return Main.LocalPlayerID; }
|
||||
}
|
||||
public static int LocalPlayerID => Main.LocalPlayerID;
|
||||
|
||||
/// <summary>
|
||||
/// Check if player is connected to a server
|
||||
/// </summary>
|
||||
public static bool IsOnServer { get { return Networking.IsOnServer; } }
|
||||
public static bool IsOnServer => Networking.IsOnServer;
|
||||
|
||||
/// <summary>
|
||||
/// Get an <see cref="System.Net.IPEndPoint"/> that the player is currently connected to, or null if not connected to the server
|
||||
/// </summary>
|
||||
public static System.Net.IPEndPoint ServerEndPoint { get { return Networking.IsOnServer ? Networking.ServerConnection?.RemoteEndPoint : null; } }
|
||||
public static System.Net.IPEndPoint ServerEndPoint => Networking.IsOnServer ? Networking.ServerConnection?.RemoteEndPoint : null;
|
||||
|
||||
/// <summary>
|
||||
/// Check if a RAGECOOP menu is visible
|
||||
/// </summary>
|
||||
public static bool IsMenuVisible
|
||||
{
|
||||
get { return Menus.CoopMenu.MenuPool.AreAnyVisible; }
|
||||
}
|
||||
public static bool IsMenuVisible => Menus.CoopMenu.MenuPool.AreAnyVisible;
|
||||
|
||||
/// <summary>
|
||||
/// Check if the RAGECOOP chat is visible
|
||||
/// </summary>
|
||||
public static bool IsChatFocused
|
||||
{
|
||||
get { return Main.MainChat.Focused; }
|
||||
}
|
||||
public static bool IsChatFocused => Main.MainChat.Focused;
|
||||
|
||||
/// <summary>
|
||||
/// Check if the RAGECOOP list of players is visible
|
||||
/// </summary>
|
||||
public static bool IsPlayerListVisible
|
||||
{
|
||||
get { return Util.GetTickCount64() - PlayerList.Pressed < 5000; }
|
||||
}
|
||||
public static bool IsPlayerListVisible => Util.GetTickCount64() - PlayerList.Pressed < 5000;
|
||||
|
||||
/// <summary>
|
||||
/// Get the version of RAGECOOP
|
||||
/// </summary>
|
||||
public static Version CurrentVersion
|
||||
{
|
||||
get { return Main.Version; }
|
||||
}
|
||||
|
||||
public static Version CurrentVersion => Main.Version;
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="Core.Logger"/> that RAGECOOP is currently using.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Logger Logger
|
||||
{
|
||||
get
|
||||
{
|
||||
return Main.Logger;
|
||||
}
|
||||
}
|
||||
public static Logger Logger => Main.Logger;
|
||||
/// <summary>
|
||||
/// Get all players indexed by their ID
|
||||
/// </summary>
|
||||
public static Dictionary<int, Player> Players => new Dictionary<int, Player>(PlayerList.Players);
|
||||
|
||||
#endregion
|
||||
|
||||
#region FUNCTIONS
|
||||
@ -246,6 +229,15 @@ namespace RageCoop.Client.Scripting
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List all servers from master server address
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<ServerInfo> ListServers()
|
||||
{
|
||||
return JsonConvert.DeserializeObject<List<ServerInfo>>(HttpHelper.DownloadString(Main.Settings.MasterServer));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send a local chat message to this player
|
||||
/// </summary>
|
||||
|
@ -46,7 +46,7 @@ namespace RageCoop.Client.Scripting
|
||||
int weather1 = default(int);
|
||||
int weather2 = default(int);
|
||||
float percent2 = default(float);
|
||||
Function.Call(Hash._GET_WEATHER_TYPE_TRANSITION, &weather1, &weather2, &percent2);
|
||||
Function.Call(Hash.GET_CURR_WEATHER_STATE, &weather1, &weather2, &percent2);
|
||||
API.SendCustomEvent(CustomEvents.WeatherTimeSync, time.Hours, time.Minutes, time.Seconds, weather1, weather2, percent2);
|
||||
}
|
||||
});
|
||||
@ -60,7 +60,7 @@ namespace RageCoop.Client.Scripting
|
||||
private void WeatherTimeSync(CustomEventReceivedArgs e)
|
||||
{
|
||||
World.CurrentTimeOfDay = new TimeSpan((int)e.Args[0], (int)e.Args[1], (int)e.Args[2]);
|
||||
Function.Call(Hash._SET_WEATHER_TYPE_TRANSITION, (int)e.Args[3], (int)e.Args[4], (float)e.Args[5]);
|
||||
Function.Call(Hash.SET_CURR_WEATHER_STATE, (int)e.Args[3], (int)e.Args[4], (float)e.Args[5]);
|
||||
}
|
||||
|
||||
private void SetDisplayNameTag(CustomEventReceivedArgs e)
|
||||
@ -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));
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ namespace RageCoop.Client.Scripting
|
||||
/// <summary>
|
||||
/// Eqivalent of <see cref="ClientResource.Logger"/> in <see cref="CurrentResource"/>
|
||||
/// </summary>
|
||||
public Core.Logger Logger { get { return CurrentResource.Logger; } }
|
||||
public Core.Logger Logger => CurrentResource.Logger;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -38,9 +38,11 @@ namespace RageCoop.Client.Scripting
|
||||
}
|
||||
internal class Resources
|
||||
{
|
||||
private readonly List<ClientResource> LoadedResources = new List<ClientResource>();
|
||||
private const string BaseScriptType = "RageCoop.Client.Scripting.ClientScript";
|
||||
private Logger Logger { get; set; }
|
||||
public Resources()
|
||||
{
|
||||
BaseScriptType = "RageCoop.Client.Scripting.ClientScript";
|
||||
Logger = Main.Logger;
|
||||
}
|
||||
private void StartAll()
|
||||
@ -106,9 +108,6 @@ namespace RageCoop.Client.Scripting
|
||||
}
|
||||
LoadedResources.Clear();
|
||||
}
|
||||
private List<ClientResource> LoadedResources = new List<ClientResource>();
|
||||
private string BaseScriptType;
|
||||
public Logger Logger { get; set; }
|
||||
|
||||
private void LoadResource(ZipFile file, string dataFolderRoot)
|
||||
{
|
||||
|
@ -7,7 +7,7 @@ namespace RageCoop.Client
|
||||
{
|
||||
public RSA ServerRSA { get; set; }
|
||||
public Aes ClientAes { get; set; } = Aes.Create();
|
||||
private Logger Logger;
|
||||
private readonly Logger Logger;
|
||||
public Security(Logger logger)
|
||||
{
|
||||
Logger = logger;
|
||||
|
@ -22,7 +22,7 @@ namespace RageCoop.Client
|
||||
/// <summary>
|
||||
/// Don't use it!
|
||||
/// </summary>
|
||||
public string MasterServer { get; set; } = "https://masterserver.ragecoop.online/";
|
||||
public string MasterServer { get; set; } = "https://masterserver.ragecoop.com/";
|
||||
/// <summary>
|
||||
/// Don't use it!
|
||||
/// </summary>
|
||||
@ -51,7 +51,7 @@ namespace RageCoop.Client
|
||||
/// <summary>
|
||||
/// Disable world NPC traffic, mission entities won't be affected
|
||||
/// </summary>
|
||||
public bool DisableTraffic { get; set; } = true;
|
||||
public bool DisableTraffic { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Bring up pause menu but don't freeze time when FrontEndPauseAlternate(Esc) is pressed.
|
||||
|
@ -116,10 +116,10 @@ namespace RageCoop.Client
|
||||
|
||||
case unchecked((uint)-1357824103):
|
||||
case unchecked((uint)-1074790547):
|
||||
case unchecked((uint)2132975508):
|
||||
case unchecked(2132975508):
|
||||
case unchecked((uint)-2084633992):
|
||||
case unchecked((uint)-952879014):
|
||||
case unchecked((uint)100416529):
|
||||
case unchecked(100416529):
|
||||
case unchecked((uint)WeaponHash.Gusenberg):
|
||||
case unchecked((uint)WeaponHash.MG):
|
||||
case unchecked((uint)WeaponHash.CombatMG):
|
||||
|
81
RageCoop.Client/Sync/Entities/Ped/SyncedPed.Members.cs
Normal file
81
RageCoop.Client/Sync/Entities/Ped/SyncedPed.Members.cs
Normal file
@ -0,0 +1,81 @@
|
||||
using GTA;
|
||||
using GTA.Math;
|
||||
using RageCoop.Core;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// ?
|
||||
/// </summary>
|
||||
public partial class SyncedPed : SyncedEntity
|
||||
{
|
||||
internal Blip PedBlip = null;
|
||||
internal BlipColor BlipColor = (BlipColor)255;
|
||||
internal BlipSprite BlipSprite = 0;
|
||||
internal float BlipScale = 1;
|
||||
internal int VehicleID
|
||||
{
|
||||
get => CurrentVehicle?.ID ?? 0;
|
||||
set
|
||||
{
|
||||
if (CurrentVehicle == null || value != CurrentVehicle?.ID)
|
||||
{
|
||||
CurrentVehicle = EntityPool.GetVehicleByID(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
internal SyncedVehicle CurrentVehicle { get; private set; }
|
||||
internal VehicleSeat Seat;
|
||||
public bool IsPlayer { get => OwnerID == ID && ID != 0; }
|
||||
public Ped MainPed { get; internal set; }
|
||||
internal int Health { get; set; }
|
||||
|
||||
internal Vector3 HeadPosition { get; set; }
|
||||
internal Vector3 RightFootPosition { get; set; }
|
||||
internal Vector3 LeftFootPosition { get; set; }
|
||||
|
||||
internal byte WeaponTint { get; set; }
|
||||
private bool _lastRagdoll = false;
|
||||
private ulong _lastRagdollTime = 0;
|
||||
private bool _lastInCover = false;
|
||||
private byte[] _lastClothes = null;
|
||||
internal byte[] Clothes { get; set; }
|
||||
|
||||
internal float Heading { get; set; }
|
||||
|
||||
internal ulong LastSpeakingTime { get; set; } = 0;
|
||||
internal bool IsSpeaking { get; set; } = false;
|
||||
public byte Speed { get; set; }
|
||||
private bool _lastIsJumping = false;
|
||||
internal PedDataFlags Flags;
|
||||
|
||||
internal bool IsAiming => Flags.HasPedFlag(PedDataFlags.IsAiming);
|
||||
internal bool _lastDriveBy;
|
||||
internal bool IsReloading => Flags.HasPedFlag(PedDataFlags.IsReloading);
|
||||
internal bool IsJumping => Flags.HasPedFlag(PedDataFlags.IsJumping);
|
||||
internal bool IsRagdoll => Flags.HasPedFlag(PedDataFlags.IsRagdoll);
|
||||
internal bool IsOnFire => Flags.HasPedFlag(PedDataFlags.IsOnFire);
|
||||
internal bool IsInParachuteFreeFall => Flags.HasPedFlag(PedDataFlags.IsInParachuteFreeFall);
|
||||
internal bool IsParachuteOpen => Flags.HasPedFlag(PedDataFlags.IsParachuteOpen);
|
||||
internal bool IsOnLadder => Flags.HasPedFlag(PedDataFlags.IsOnLadder);
|
||||
internal bool IsVaulting => Flags.HasPedFlag(PedDataFlags.IsVaulting);
|
||||
internal bool IsInCover => Flags.HasPedFlag(PedDataFlags.IsInCover);
|
||||
internal bool IsInLowCover => Flags.HasPedFlag(PedDataFlags.IsInLowCover);
|
||||
internal bool IsInCoverFacingLeft => Flags.HasPedFlag(PedDataFlags.IsInCoverFacingLeft);
|
||||
internal bool IsBlindFiring => Flags.HasPedFlag(PedDataFlags.IsBlindFiring);
|
||||
internal bool IsInStealthMode => Flags.HasPedFlag(PedDataFlags.IsInStealthMode);
|
||||
internal Prop ParachuteProp { get; set; } = null;
|
||||
internal uint CurrentWeaponHash { get; set; }
|
||||
private Dictionary<uint, bool> _lastWeaponComponents = null;
|
||||
internal Dictionary<uint, bool> WeaponComponents { get; set; } = null;
|
||||
private Entity _weaponObj;
|
||||
internal Vector3 AimCoords { get; set; }
|
||||
|
||||
|
||||
private readonly string[] _currentAnimation = new string[2] { "", "" };
|
||||
|
||||
private bool LastMoving;
|
||||
|
||||
}
|
||||
}
|
@ -15,7 +15,6 @@ namespace RageCoop.Client
|
||||
/// </summary>
|
||||
public partial class SyncedPed : SyncedEntity
|
||||
{
|
||||
#region CONSTRUCTORS
|
||||
|
||||
/// <summary>
|
||||
/// Create a local entity (outgoing sync)
|
||||
@ -29,7 +28,7 @@ namespace RageCoop.Client
|
||||
MainPed = p;
|
||||
OwnerID = Main.LocalPlayerID;
|
||||
|
||||
Function.Call(Hash._SET_PED_CAN_PLAY_INJURED_ANIMS, false);
|
||||
Function.Call(Hash.SET_PED_IS_IGNORED_BY_AUTO_OPEN_DOORS, false);
|
||||
MainPed.SetConfigFlag((int)PedConfigFlags.CPED_CONFIG_FLAG_DisableHurt, true);
|
||||
// MainPed.SetConfigFlag((int)PedConfigFlags.CPED_CONFIG_FLAG_DisableMelee, true);
|
||||
|
||||
@ -43,75 +42,6 @@ namespace RageCoop.Client
|
||||
ID = id;
|
||||
LastSynced = Main.Ticked;
|
||||
}
|
||||
#endregion
|
||||
internal Blip PedBlip = null;
|
||||
internal BlipColor BlipColor = (BlipColor)255;
|
||||
internal BlipSprite BlipSprite = 0;
|
||||
internal float BlipScale = 1;
|
||||
internal int VehicleID
|
||||
{
|
||||
get => CurrentVehicle?.ID ?? 0;
|
||||
set
|
||||
{
|
||||
if (CurrentVehicle == null || value != CurrentVehicle?.ID)
|
||||
{
|
||||
CurrentVehicle=EntityPool.GetVehicleByID(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
internal SyncedVehicle CurrentVehicle { get; private set; }
|
||||
internal VehicleSeat Seat;
|
||||
public bool IsPlayer { get => OwnerID == ID && ID != 0; }
|
||||
public Ped MainPed { get; internal set; }
|
||||
internal int Health { get; set; }
|
||||
|
||||
internal Vector3 HeadPosition { get; set; }
|
||||
internal Vector3 RightFootPosition { get; set; }
|
||||
internal Vector3 LeftFootPosition { get; set; }
|
||||
|
||||
internal byte WeaponTint { get; set; }
|
||||
internal Vehicle _lastVehicle { get; set; }
|
||||
internal int _lastVehicleID { get; set; }
|
||||
private bool _lastRagdoll = false;
|
||||
private ulong _lastRagdollTime = 0;
|
||||
private bool _lastInCover = false;
|
||||
private byte[] _lastClothes = null;
|
||||
internal byte[] Clothes { get; set; }
|
||||
|
||||
internal float Heading { get; set; }
|
||||
|
||||
internal ulong LastSpeakingTime { get; set; } = 0;
|
||||
internal bool IsSpeaking { get; set; } = false;
|
||||
|
||||
#region -- VARIABLES --
|
||||
public byte Speed { get; set; }
|
||||
private bool _lastIsJumping = false;
|
||||
internal PedDataFlags Flags;
|
||||
|
||||
internal bool IsAiming => Flags.HasPedFlag(PedDataFlags.IsAiming);
|
||||
internal bool _lastDriveBy;
|
||||
internal bool IsReloading => Flags.HasPedFlag(PedDataFlags.IsReloading);
|
||||
internal bool IsJumping => Flags.HasPedFlag(PedDataFlags.IsJumping);
|
||||
internal bool IsRagdoll => Flags.HasPedFlag(PedDataFlags.IsRagdoll);
|
||||
internal bool IsOnFire => Flags.HasPedFlag(PedDataFlags.IsOnFire);
|
||||
internal bool IsInParachuteFreeFall => Flags.HasPedFlag(PedDataFlags.IsInParachuteFreeFall);
|
||||
internal bool IsParachuteOpen => Flags.HasPedFlag(PedDataFlags.IsParachuteOpen);
|
||||
internal bool IsOnLadder => Flags.HasPedFlag(PedDataFlags.IsOnLadder);
|
||||
internal bool IsVaulting => Flags.HasPedFlag(PedDataFlags.IsVaulting);
|
||||
internal bool IsInCover => Flags.HasPedFlag(PedDataFlags.IsInCover);
|
||||
internal bool IsInLowCover => Flags.HasPedFlag(PedDataFlags.IsInLowCover);
|
||||
internal bool IsInCoverFacingLeft => Flags.HasPedFlag(PedDataFlags.IsInCoverFacingLeft);
|
||||
internal bool IsBlindFiring => Flags.HasPedFlag(PedDataFlags.IsBlindFiring);
|
||||
internal bool IsInStealthMode => Flags.HasPedFlag(PedDataFlags.IsInStealthMode);
|
||||
internal Prop ParachuteProp { get; set; } = null;
|
||||
internal uint CurrentWeaponHash { get; set; }
|
||||
private Dictionary<uint, bool> _lastWeaponComponents = null;
|
||||
internal Dictionary<uint, bool> WeaponComponents { get; set; } = null;
|
||||
private Entity _weaponObj;
|
||||
#endregion
|
||||
internal Vector3 AimCoords { get; set; }
|
||||
|
||||
private WeaponAsset WeaponAsset { get; set; }
|
||||
|
||||
internal override void Update()
|
||||
{
|
||||
@ -305,7 +235,7 @@ namespace RageCoop.Client
|
||||
Function.Call(Hash.SET_PED_CAN_BE_TARGETTED_BY_PLAYER, MainPed.Handle, Game.Player, true);
|
||||
Function.Call(Hash.SET_PED_GET_OUT_UPSIDE_DOWN_VEHICLE, MainPed.Handle, false);
|
||||
Function.Call(Hash.SET_CAN_ATTACK_FRIENDLY, MainPed.Handle, true, true);
|
||||
Function.Call(Hash._SET_PED_CAN_PLAY_INJURED_ANIMS, false);
|
||||
Function.Call(Hash.SET_PED_IS_IGNORED_BY_AUTO_OPEN_DOORS, false);
|
||||
Function.Call(Hash.SET_PED_CAN_EVASIVE_DIVE, MainPed.Handle, false);
|
||||
|
||||
MainPed.SetConfigFlag((int)PedConfigFlags.CPED_CONFIG_FLAG_DrownsInWater, false);
|
||||
@ -343,9 +273,6 @@ namespace RageCoop.Client
|
||||
}
|
||||
|
||||
|
||||
#region ONFOOT
|
||||
private string[] _currentAnimation = new string[2] { "", "" };
|
||||
|
||||
private void DisplayOnFoot()
|
||||
{
|
||||
|
||||
@ -506,8 +433,6 @@ namespace RageCoop.Client
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (MainPed.IsRagdoll)
|
||||
{
|
||||
if (Speed == 0)
|
||||
@ -518,10 +443,8 @@ namespace RageCoop.Client
|
||||
{
|
||||
MainPed.Task.ClearAllImmediately();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
_lastRagdoll = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsReloading)
|
||||
@ -581,12 +504,12 @@ namespace RageCoop.Client
|
||||
}
|
||||
}
|
||||
|
||||
#region WEAPON
|
||||
private void CheckCurrentWeapon()
|
||||
{
|
||||
if (MainPed.Weapons.Current.Hash != (WeaponHash)CurrentWeaponHash || !WeaponComponents.Compare(_lastWeaponComponents) || (Speed <= 3 && _weaponObj?.IsVisible != true))
|
||||
{
|
||||
WeaponAsset=new WeaponAsset(CurrentWeaponHash);
|
||||
new WeaponAsset(CurrentWeaponHash).Request();
|
||||
|
||||
MainPed.Weapons.RemoveAll();
|
||||
_weaponObj = Entity.FromHandle(Function.Call<int>(Hash.CREATE_WEAPON_OBJECT, CurrentWeaponHash, -1, Position.X, Position.Y, Position.Z, true, 0, 0));
|
||||
if (_weaponObj == null) { return; }
|
||||
@ -627,9 +550,7 @@ namespace RageCoop.Client
|
||||
}
|
||||
SmoothTransition();
|
||||
}
|
||||
#endregion
|
||||
|
||||
private bool LastMoving;
|
||||
private void WalkTo()
|
||||
{
|
||||
MainPed.Task.ClearAll();
|
||||
@ -750,10 +671,6 @@ namespace RageCoop.Client
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
private void DisplayInVehicle()
|
||||
{
|
||||
if (CurrentVehicle?.MainVehicle == null) { return; }
|
||||
@ -796,7 +713,7 @@ namespace RageCoop.Client
|
||||
case 5:
|
||||
if (MainPed.VehicleTryingToEnter != CurrentVehicle.MainVehicle || MainPed.GetSeatTryingToEnter() != Seat)
|
||||
{
|
||||
MainPed.Task.EnterVehicle(CurrentVehicle.MainVehicle,Seat,-1,5,EnterVehicleFlags.AllowJacking);
|
||||
MainPed.Task.EnterVehicle(CurrentVehicle.MainVehicle, Seat, -1, 5, EnterVehicleFlags.JackAnyone);
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
|
@ -36,7 +36,8 @@ namespace RageCoop.Client
|
||||
if (value == _ownerID && Owner != null) { return; }
|
||||
_ownerID = value;
|
||||
Owner = PlayerList.GetPlayer(value);
|
||||
if(this is SyncedPed && Owner!=null){
|
||||
if (this is SyncedPed && Owner != null)
|
||||
{
|
||||
Owner.Character = ((SyncedPed)this);
|
||||
}
|
||||
}
|
||||
@ -83,7 +84,7 @@ namespace RageCoop.Client
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
internal protected bool _lastFrozen = false;
|
||||
protected internal bool _lastFrozen = false;
|
||||
internal Model Model { get; set; }
|
||||
internal Vector3 Position { get; set; }
|
||||
internal Vector3 Rotation { get; set; }
|
||||
|
@ -1,7 +1,7 @@
|
||||
using GTA;
|
||||
using GTA.Math;
|
||||
using RageCoop.Core;
|
||||
using GTA.Native;
|
||||
using RageCoop.Core;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -19,12 +19,11 @@ namespace RageCoop.Client
|
||||
public SyncedEntity Shooter { get; set; }
|
||||
public bool Exploded => Flags.HasProjDataFlag(ProjectileDataFlags.Exploded);
|
||||
|
||||
internal override Player Owner => Shooter.Owner;
|
||||
/// <summary>
|
||||
/// Invalid property for projectile.
|
||||
/// </summary>
|
||||
private new int OwnerID { set { } }
|
||||
|
||||
internal override Player Owner => Shooter.Owner;
|
||||
public WeaponHash WeaponHash { get; set; }
|
||||
private WeaponAsset Asset { get; set; }
|
||||
public void ExtractData(ref Packets.ProjectileSync p)
|
||||
@ -101,7 +100,7 @@ namespace RageCoop.Client
|
||||
CreateProjectile();
|
||||
return;
|
||||
}
|
||||
MainProjectile.Velocity=Velocity+(Position+Shooter.Owner.PacketTravelTime*Velocity-MainProjectile.Position);
|
||||
MainProjectile.Velocity = Velocity + 10 * (Predict(Position) - MainProjectile.Position);
|
||||
MainProjectile.Rotation = Rotation;
|
||||
LastUpdated = Main.Ticked;
|
||||
}
|
||||
@ -113,15 +112,14 @@ namespace RageCoop.Client
|
||||
if (Shooter == null) { return; }
|
||||
Entity owner;
|
||||
owner = (Shooter as SyncedPed)?.MainPed ?? (Entity)(Shooter as SyncedVehicle)?.MainVehicle;
|
||||
Position = (Owner.PacketTravelTime + 0.001f * LastSyncedStopWatch.ElapsedMilliseconds) * Shooter.Velocity + Position;
|
||||
var end = Position + Velocity;
|
||||
Function.Call(Hash.SHOOT_SINGLE_BULLET_BETWEEN_COORDS_IGNORE_ENTITY, Position.X, Position.Y, Position.Z, end.X, end.Y, end.Z, 0, 1, WeaponHash, owner?.Handle ?? 0, 1, 0, -1,owner);
|
||||
Function.Call(Hash.SHOOT_SINGLE_BULLET_BETWEEN_COORDS_IGNORE_ENTITY, Position.X, Position.Y, Position.Z, end.X, end.Y, end.Z, 0, 1, WeaponHash, owner?.Handle ?? 0, 1, 0, -1);
|
||||
var ps = World.GetAllProjectiles();
|
||||
MainProjectile = ps[ps.Length - 1];
|
||||
MainProjectile.IsCollisionEnabled=false;
|
||||
MainProjectile.Position = Position;
|
||||
MainProjectile.Rotation = Rotation;
|
||||
MainProjectile.Velocity = Velocity;
|
||||
Main.Delay(()=>MainProjectile.IsCollisionEnabled=true, 100);
|
||||
EntityPool.Add(this);
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
using System;
|
||||
using RageCoop.Core;
|
||||
using GTA;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using GTA.Math;
|
||||
using GTA.Native;
|
||||
using RageCoop.Core;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RageCoop.Client{
|
||||
public partial class SyncedVehicle{
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
public partial class SyncedVehicle
|
||||
{
|
||||
public Vehicle MainVehicle { get; internal set; }
|
||||
|
||||
|
||||
@ -68,11 +67,9 @@ namespace RageCoop.Client{
|
||||
private bool _lastHornActive = false;
|
||||
private bool _lastTransformed = false;
|
||||
internal int _lastLivery = -1;
|
||||
List<Vector3> _predictedTrace = new List<Vector3>();
|
||||
List<Vector3> _orgTrace = new List<Vector3>();
|
||||
private readonly List<Vector3> _predictedTrace = new List<Vector3>();
|
||||
private readonly List<Vector3> _orgTrace = new List<Vector3>();
|
||||
private Vector3 _predictedPosition;
|
||||
|
||||
float _elapsed;
|
||||
#endregion
|
||||
|
||||
#region OUTGOING
|
||||
|
@ -4,8 +4,6 @@ using GTA.Native;
|
||||
using RageCoop.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -31,7 +29,9 @@ namespace RageCoop.Client
|
||||
SetUpFixedData();
|
||||
|
||||
}
|
||||
private void SetUpFixedData(){
|
||||
internal void SetUpFixedData()
|
||||
{
|
||||
if (MainVehicle == null) { return; }
|
||||
|
||||
IsAircraft = MainVehicle.IsAircraft;
|
||||
IsMotorcycle = MainVehicle.IsMotorcycle;
|
||||
@ -149,8 +149,6 @@ namespace RageCoop.Client
|
||||
MainVehicle.AreHighBeamsOn = HighBeamsOn;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (IsAircraft)
|
||||
{
|
||||
if (LandingGear != (byte)MainVehicle.LandingGearState)
|
||||
@ -184,10 +182,12 @@ namespace RageCoop.Client
|
||||
MainVehicle.RoofState = RoofState;
|
||||
}
|
||||
|
||||
if(HasRocketBoost && Flags.HasFlag(VehicleDataFlags.IsRocketBoostActive) != MainVehicle.IsRocketBoostActive()){
|
||||
if (HasRocketBoost && Flags.HasFlag(VehicleDataFlags.IsRocketBoostActive) != MainVehicle.IsRocketBoostActive())
|
||||
{
|
||||
MainVehicle.SetRocketBoostActive(Flags.HasFlag(VehicleDataFlags.IsRocketBoostActive));
|
||||
}
|
||||
if(HasParachute && Flags.HasFlag(VehicleDataFlags.IsParachuteActive) != MainVehicle.IsParachuteActive()){
|
||||
if (HasParachute && Flags.HasFlag(VehicleDataFlags.IsParachuteActive) != MainVehicle.IsParachuteActive())
|
||||
{
|
||||
MainVehicle.SetParachuteActive(Flags.HasFlag(VehicleDataFlags.IsParachuteActive));
|
||||
}
|
||||
if (IsSubmarineCar)
|
||||
@ -197,13 +197,13 @@ namespace RageCoop.Client
|
||||
if (!_lastTransformed)
|
||||
{
|
||||
_lastTransformed = true;
|
||||
Function.Call(Hash._TRANSFORM_VEHICLE_TO_SUBMARINE, MainVehicle.Handle, false);
|
||||
Function.Call(Hash.TRANSFORM_TO_SUBMARINE, MainVehicle.Handle, false);
|
||||
}
|
||||
}
|
||||
else if (_lastTransformed)
|
||||
{
|
||||
_lastTransformed = false;
|
||||
Function.Call(Hash._TRANSFORM_SUBMARINE_TO_VEHICLE, MainVehicle.Handle, false);
|
||||
Function.Call(Hash.TRANSFORM_TO_CAR, MainVehicle.Handle, false);
|
||||
}
|
||||
}
|
||||
else if (IsDeluxo)
|
||||
@ -260,7 +260,8 @@ namespace RageCoop.Client
|
||||
}
|
||||
LastUpdated = Main.Ticked;
|
||||
}
|
||||
void DisplayVehicle()
|
||||
|
||||
private void DisplayVehicle()
|
||||
{
|
||||
_predictedPosition = Predict(Position);
|
||||
var current = MainVehicle.ReadPosition();
|
||||
@ -274,7 +275,7 @@ namespace RageCoop.Client
|
||||
MainVehicle.Quaternion = Quaternion;
|
||||
return;
|
||||
}
|
||||
else if (dist > 0.03)
|
||||
if (dist > 0.03)
|
||||
{
|
||||
MainVehicle.Velocity = Velocity + cali;
|
||||
}
|
||||
@ -286,11 +287,8 @@ namespace RageCoop.Client
|
||||
MainVehicle.RotationVelocity = RotationVelocity;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
MainVehicle.RotationVelocity = RotationVelocity + calirot * 0.2f;
|
||||
}
|
||||
}
|
||||
private Vector3 GetCalibrationRotation()
|
||||
{
|
||||
var rot = Quaternion.LookRotation(Quaternion * Vector3.RelativeFront, Quaternion * Vector3.RelativeTop).ToEulerAngles();
|
||||
@ -316,7 +314,7 @@ namespace RageCoop.Client
|
||||
// GTA.UI.Notification.Show($"~r~(Vehicle)Model ({CurrentVehicleModelHash}) cannot be loaded!");
|
||||
return false;
|
||||
}
|
||||
else if (MainVehicle==null)
|
||||
if (MainVehicle == null)
|
||||
{
|
||||
Model.Request();
|
||||
return false;
|
||||
@ -366,7 +364,7 @@ namespace RageCoop.Client
|
||||
|
||||
private void StartPedalingAnim(bool fast)
|
||||
{
|
||||
MainVehicle.Driver?.Task.PlayAnimation(PedalingAnimDict(), PedalingAnimName(fast), 8.0f, -8.0f, -1, AnimationFlags.Loop | AnimationFlags.AllowRotation, 1.0f);
|
||||
MainVehicle.Driver?.Task.PlayAnimation(PedalingAnimDict(), PedalingAnimName(fast), 8.0f, -8.0f, -1, AnimationFlags.Loop | AnimationFlags.Secondary, 1.0f);
|
||||
|
||||
}
|
||||
|
||||
@ -375,7 +373,5 @@ namespace RageCoop.Client
|
||||
MainVehicle.Driver.Task.ClearAnimation(PedalingAnimDict(), PedalingAnimName(fast));
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,17 @@
|
||||
using GTA;
|
||||
using GTA.Native;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Client.Scripting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
internal class EntityPool
|
||||
{
|
||||
public static object PedsLock = new object();
|
||||
public static int CharactersCount { get { return PedsByID.Count; } }
|
||||
#if BENCHMARK
|
||||
private static Stopwatch PerfCounter=new Stopwatch();
|
||||
private static Stopwatch PerfCounter2=Stopwatch.StartNew();
|
||||
@ -44,10 +43,10 @@ namespace RageCoop.Client
|
||||
#endregion
|
||||
public static void Cleanup(bool keepPlayer = true, bool keepMine = true)
|
||||
{
|
||||
foreach (int id in new List<int>(PedsByID.Keys))
|
||||
foreach (var ped in PedsByID.Values)
|
||||
{
|
||||
if (keepPlayer && (id==Main.LocalPlayerID)|| keepMine && (PedsByID[id].OwnerID == Main.LocalPlayerID)) { continue; }
|
||||
RemovePed(id);
|
||||
if ((keepPlayer && (ped.ID == Main.LocalPlayerID)) || (keepMine && (ped.OwnerID == Main.LocalPlayerID))) { continue; }
|
||||
RemovePed(ped.ID);
|
||||
}
|
||||
PedsByID.Clear();
|
||||
PedsByHandle.Clear();
|
||||
@ -289,11 +288,11 @@ namespace RageCoop.Client
|
||||
public static bool VehicleExists(int id) => VehiclesByID.ContainsKey(id);
|
||||
public static bool ProjectileExists(int id) => ProjectilesByID.ContainsKey(id);
|
||||
#endregion
|
||||
static int vehStateIndex;
|
||||
static int pedStateIndex;
|
||||
static int vehStatesPerFrame;
|
||||
static int pedStatesPerFrame;
|
||||
static int i;
|
||||
private static int vehStateIndex;
|
||||
private static int pedStateIndex;
|
||||
private static int vehStatesPerFrame;
|
||||
private static int pedStatesPerFrame;
|
||||
private static int i;
|
||||
public static Ped[] allPeds = new Ped[0];
|
||||
public static Vehicle[] allVehicles = new Vehicle[0];
|
||||
public static Projectile[] allProjectiles = new Projectile[0];
|
||||
@ -310,17 +309,6 @@ namespace RageCoop.Client
|
||||
allProjectiles = World.GetAllProjectiles();
|
||||
vehStatesPerFrame = allVehicles.Length * 2 / (int)Game.FPS + 1;
|
||||
pedStatesPerFrame = allPeds.Length * 2 / (int)Game.FPS + 1;
|
||||
/*
|
||||
if (Main.Ticked%50==0)
|
||||
{
|
||||
bool flag1 = allVehicles.Length>Main.Settings.WorldVehicleSoftLimit && Main.Settings.WorldVehicleSoftLimit>-1;
|
||||
bool flag2 = allPeds.Length>Main.Settings.WorldPedSoftLimit && Main.Settings.WorldPedSoftLimit>-1;
|
||||
if ((flag1||flag2) && _trafficSpawning)
|
||||
{ SetBudget(0); _trafficSpawning=false; }
|
||||
else if(!_trafficSpawning)
|
||||
{ SetBudget(1); _trafficSpawning=true; }
|
||||
}
|
||||
*/
|
||||
#if BENCHMARK
|
||||
|
||||
Debug.TimeStamps[TimeStamp.GetAllEntities]=PerfCounter.ElapsedTicks;
|
||||
@ -345,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.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;
|
||||
}
|
||||
@ -370,14 +358,14 @@ namespace RageCoop.Client
|
||||
|
||||
lock (PedsLock)
|
||||
{
|
||||
EntityPool.AddPlayer();
|
||||
AddPlayer();
|
||||
|
||||
foreach (Ped p in allPeds)
|
||||
{
|
||||
SyncedPed c = EntityPool.GetPedByHandle(p.Handle);
|
||||
SyncedPed c = GetPedByHandle(p.Handle);
|
||||
if (c == null && (p != Game.Player.Character))
|
||||
{
|
||||
if (allPeds.Length>Main.Settings.WorldPedSoftLimit && p.PopulationType != EntityPopulationType.RandomAmbient)
|
||||
if (allPeds.Length > Main.Settings.WorldPedSoftLimit && p.PopulationType == EntityPopulationType.RandomAmbient && !p.IsInVehicle())
|
||||
{
|
||||
p.Delete();
|
||||
continue;
|
||||
@ -385,7 +373,7 @@ namespace RageCoop.Client
|
||||
// Main.Logger.Trace($"Creating SyncEntity for ped, handle:{p.Handle}");
|
||||
c = new SyncedPed(p);
|
||||
|
||||
EntityPool.Add(c);
|
||||
Add(c);
|
||||
}
|
||||
}
|
||||
#if BENCHMARK
|
||||
@ -404,7 +392,7 @@ namespace RageCoop.Client
|
||||
i++;
|
||||
if ((c.MainPed != null) && (!c.MainPed.Exists()))
|
||||
{
|
||||
EntityPool.RemovePed(c.ID, "non-existent");
|
||||
RemovePed(c.ID, "non-existent");
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -441,9 +429,8 @@ namespace RageCoop.Client
|
||||
Debug.TimeStamps[TimeStamp.PedTotal]=PerfCounter.ElapsedTicks;
|
||||
#endif
|
||||
}
|
||||
|
||||
var check = Main.Ticked % 100 == 0;
|
||||
i = -1;
|
||||
|
||||
lock (VehiclesLock)
|
||||
{
|
||||
foreach (Vehicle veh in allVehicles)
|
||||
@ -458,10 +445,10 @@ namespace RageCoop.Client
|
||||
foreach (var p in veh.Occupants)
|
||||
{
|
||||
p.Delete();
|
||||
var c = EntityPool.GetPedByHandle(p.Handle);
|
||||
var c = GetPedByHandle(p.Handle);
|
||||
if (c != null)
|
||||
{
|
||||
EntityPool.RemovePed(c.ID, "ThrottleTraffic");
|
||||
RemovePed(c.ID, "ThrottleTraffic");
|
||||
}
|
||||
}
|
||||
veh.Delete();
|
||||
@ -488,10 +475,13 @@ namespace RageCoop.Client
|
||||
i++;
|
||||
if ((v.MainVehicle != null) && (!v.MainVehicle.Exists()))
|
||||
{
|
||||
EntityPool.RemoveVehicle(v.ID, "non-existent");
|
||||
RemoveVehicle(v.ID, "non-existent");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (check)
|
||||
{
|
||||
v.SetUpFixedData();
|
||||
}
|
||||
// Outgoing sync
|
||||
if (v.IsLocal)
|
||||
{
|
||||
@ -516,7 +506,8 @@ namespace RageCoop.Client
|
||||
}
|
||||
Networking.Peer.FlushSendQueue();
|
||||
}
|
||||
static void UpdateTargets()
|
||||
|
||||
private static void UpdateTargets()
|
||||
{
|
||||
Networking.Targets = new List<NetConnection>(PlayerList.Players.Count) { Networking.ServerConnection };
|
||||
foreach (var p in PlayerList.Players.Values.ToArray())
|
||||
@ -581,21 +572,21 @@ namespace RageCoop.Client
|
||||
{
|
||||
public static void Add(SyncedVehicle v)
|
||||
{
|
||||
lock (EntityPool.VehiclesLock)
|
||||
lock (VehiclesLock)
|
||||
{
|
||||
EntityPool.Add(v);
|
||||
}
|
||||
}
|
||||
public static void Add(SyncedPed p)
|
||||
{
|
||||
lock (EntityPool.PedsLock)
|
||||
lock (PedsLock)
|
||||
{
|
||||
EntityPool.Add(p);
|
||||
}
|
||||
}
|
||||
public static void Add(SyncedProjectile sp)
|
||||
{
|
||||
lock (EntityPool.ProjectilesLock)
|
||||
lock (ProjectilesLock)
|
||||
{
|
||||
EntityPool.Add(sp);
|
||||
}
|
||||
|
@ -1,10 +1,8 @@
|
||||
using GTA;
|
||||
using GTA.Math;
|
||||
using Lidgren.Network;
|
||||
using RageCoop.Core;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -73,9 +71,8 @@ namespace RageCoop.Client
|
||||
#region HANDLE
|
||||
|
||||
public static ParticleEffectAsset CorePFXAsset = new ParticleEffectAsset("core");
|
||||
|
||||
static WeaponAsset _weaponAsset = default;
|
||||
static uint _lastWeaponHash;
|
||||
private static WeaponAsset _weaponAsset = default;
|
||||
private static uint _lastWeaponHash;
|
||||
|
||||
private static void HandlePedKilled(Packets.PedKilled p)
|
||||
{
|
||||
@ -162,44 +159,39 @@ namespace RageCoop.Client
|
||||
WeaponUtil.GetFlashFX((WeaponHash)p.WeaponHash),
|
||||
b.Position, b.ForwardVector.ToEulerRotation(v.Bones[35].UpVector), 1);
|
||||
}
|
||||
public static void HandleEvent(PacketType type, byte[] data)
|
||||
public static void HandleEvent(PacketType type, NetIncomingMessage msg)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PacketType.BulletShot:
|
||||
{
|
||||
Packets.BulletShot p = new Packets.BulletShot();
|
||||
p.Deserialize(data);
|
||||
p.Deserialize(msg);
|
||||
HandleBulletShot(p.StartPosition, p.EndPosition, p.WeaponHash, p.OwnerID);
|
||||
break;
|
||||
}
|
||||
case PacketType.VehicleBulletShot:
|
||||
{
|
||||
HandleVehicleBulletShot(data.GetPacket<Packets.VehicleBulletShot>());
|
||||
HandleVehicleBulletShot(msg.GetPacket<Packets.VehicleBulletShot>());
|
||||
break;
|
||||
}
|
||||
case PacketType.OwnerChanged:
|
||||
{
|
||||
Packets.OwnerChanged packet = new Packets.OwnerChanged();
|
||||
packet.Deserialize(data);
|
||||
HandleOwnerChanged(packet);
|
||||
HandleOwnerChanged(msg.GetPacket<Packets.OwnerChanged>());
|
||||
}
|
||||
break;
|
||||
case PacketType.PedKilled:
|
||||
{
|
||||
var packet = new Packets.PedKilled();
|
||||
packet.Deserialize(data);
|
||||
HandlePedKilled(packet);
|
||||
HandlePedKilled(msg.GetPacket<Packets.PedKilled>());
|
||||
}
|
||||
break;
|
||||
case PacketType.NozzleTransform:
|
||||
{
|
||||
var packet = new Packets.NozzleTransform();
|
||||
packet.Deserialize(data);
|
||||
HandleNozzleTransform(packet);
|
||||
HandleNozzleTransform(msg.GetPacket<Packets.NozzleTransform>());
|
||||
break;
|
||||
}
|
||||
}
|
||||
Networking.Peer.Recycle(msg);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -1,6 +1,5 @@
|
||||
using System.Threading;
|
||||
|
||||
using NAudio.Wave;
|
||||
using NAudio.Wave;
|
||||
using System.Threading;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
|
64
RageCoop.Client/Util/AddOnDataProvider.cs
Normal file
64
RageCoop.Client/Util/AddOnDataProvider.cs
Normal file
@ -0,0 +1,64 @@
|
||||
using GTA;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// Class providing support for addon mods
|
||||
/// </summary>
|
||||
internal class AddOnDataProvider
|
||||
{
|
||||
public static int GetMuzzleIndex(Model model)
|
||||
{
|
||||
switch (model.Hash)
|
||||
{
|
||||
// f14a2
|
||||
case -848721350:
|
||||
return 48;
|
||||
|
||||
// f15e
|
||||
case 881261972:
|
||||
return 32;
|
||||
|
||||
// f16c
|
||||
case -2051171080:
|
||||
return 25;
|
||||
|
||||
// F22A
|
||||
case 2061630439:
|
||||
return 14;
|
||||
|
||||
// f35c
|
||||
case -343547392:
|
||||
return 44;
|
||||
|
||||
// mig29a
|
||||
case 513887552:
|
||||
return 18;
|
||||
|
||||
// su30sm
|
||||
case -733985185:
|
||||
return 34;
|
||||
|
||||
// su33
|
||||
case -722216722:
|
||||
return 34;
|
||||
|
||||
// su35s
|
||||
case -268602544:
|
||||
return 28;
|
||||
|
||||
// su57
|
||||
case 1490050781:
|
||||
return 21;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +1,19 @@
|
||||
|
||||
using GTA;
|
||||
using GTA.Math;
|
||||
using RageCoop.Core;
|
||||
using SHVDN;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using GTA.Math;
|
||||
using GTA;
|
||||
using SHVDN;
|
||||
using RageCoop.Core;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
internal unsafe class MemPatch{
|
||||
private byte[] _data;
|
||||
private byte[] _orginal;
|
||||
private IntPtr _address;
|
||||
internal unsafe class MemPatch
|
||||
{
|
||||
private readonly byte[] _data;
|
||||
private readonly byte[] _orginal;
|
||||
private readonly IntPtr _address;
|
||||
public MemPatch(byte* address, byte[] data)
|
||||
{
|
||||
_data = data;
|
||||
@ -68,8 +69,8 @@ internal static unsafe class Memory
|
||||
public const int MatrixOffset = 96;
|
||||
#endregion
|
||||
#region OPCODE
|
||||
const byte XOR_32_64 = 0x31;
|
||||
const byte RET = 0xC3;
|
||||
private const byte XOR_32_64 = 0x31;
|
||||
private const byte RET = 0xC3;
|
||||
#endregion
|
||||
public static Vector3 ReadPosition(this Entity e) => ReadVector3(e.MemoryAddress + PositionOffset);
|
||||
public static Quaternion ReadQuaternion(this Entity e) => Quaternion.RotationMatrix(e.Matrix);
|
||||
|
@ -1,14 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using GTA;
|
||||
using GTA.Math;
|
||||
using GTA.Native;
|
||||
using GTA.Math;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using LemonUI.Elements;
|
||||
using System.Drawing;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -68,16 +61,16 @@ namespace RageCoop.Client
|
||||
{
|
||||
// These are borrowed from ScriptHookVDotNet's
|
||||
[DllImport("ScriptHookV.dll", ExactSpelling = true, EntryPoint = "?nativeInit@@YAX_K@Z")]
|
||||
static extern void NativeInit(ulong hash);
|
||||
private static extern void NativeInit(ulong hash);
|
||||
|
||||
[DllImport("ScriptHookV.dll", ExactSpelling = true, EntryPoint = "?nativePush64@@YAX_K@Z")]
|
||||
static extern void NativePush64(ulong val);
|
||||
private static extern void NativePush64(ulong val);
|
||||
|
||||
[DllImport("ScriptHookV.dll", ExactSpelling = true, EntryPoint = "?nativeCall@@YAPEA_KXZ")]
|
||||
static extern unsafe ulong* NativeCall();
|
||||
private static extern unsafe ulong* NativeCall();
|
||||
|
||||
// These are from ScriptHookV's nativeCaller.h
|
||||
static unsafe void NativePush<T>(T val) where T : unmanaged
|
||||
private static unsafe void NativePush<T>(T val) where T : unmanaged
|
||||
{
|
||||
ulong val64 = 0;
|
||||
*(T*)(&val64) = val;
|
||||
@ -106,7 +99,7 @@ namespace RageCoop.Client
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
static unsafe ulong[] ConvertPrimitiveArguments(object[] args)
|
||||
private static unsafe ulong[] ConvertPrimitiveArguments(object[] args)
|
||||
{
|
||||
var result = new ulong[args.Length];
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
@ -118,7 +111,7 @@ namespace RageCoop.Client
|
||||
}
|
||||
if (args[i] is byte valueByte)
|
||||
{
|
||||
result[i] = (ulong)valueByte;
|
||||
result[i] = valueByte;
|
||||
continue;
|
||||
}
|
||||
if (args[i] is int valueInt32)
|
||||
|
@ -2,8 +2,8 @@
|
||||
using GTA.Math;
|
||||
using GTA.Native;
|
||||
using RageCoop.Core;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -146,7 +146,8 @@ namespace RageCoop.Client
|
||||
{
|
||||
flags |= PedDataFlags.IsInCover;
|
||||
}
|
||||
if (!Function.Call<bool>(Hash.IS_PED_IN_HIGH_COVER, ped)){
|
||||
if (!Function.Call<bool>(Hash.IS_PED_IN_HIGH_COVER, ped))
|
||||
{
|
||||
flags |= PedDataFlags.IsInLowCover;
|
||||
}
|
||||
if (ped.IsTaskActive(TaskType.CTaskAimGunBlindFire))
|
||||
@ -295,7 +296,7 @@ namespace RageCoop.Client
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
else if (veh.GetPedOnSeat(seat) != null)
|
||||
{
|
||||
|
||||
bool isDead = veh.GetPedOnSeat(seat).IsDead;
|
||||
|
@ -6,13 +6,10 @@ using System;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using System.Xml.Serialization;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("RageCoop.Client.Installer")]
|
||||
namespace RageCoop.Client
|
||||
@ -219,7 +216,7 @@ namespace RageCoop.Client
|
||||
|
||||
#region WIN32
|
||||
|
||||
const UInt32 WM_KEYDOWN = 0x0100;
|
||||
private const UInt32 WM_KEYDOWN = 0x0100;
|
||||
public static void Reload()
|
||||
{
|
||||
string reloadKey = "None";
|
||||
@ -238,6 +235,7 @@ namespace RageCoop.Client
|
||||
foreach (var l in lines)
|
||||
{
|
||||
var ss = l.Split('=');
|
||||
ss.ForEach(s => s.Replace(" ", ""));
|
||||
if (ss.Length > 0 && ss[0] == "ReloadKey")
|
||||
{
|
||||
reloadKey = ss[1];
|
||||
@ -268,7 +266,7 @@ namespace RageCoop.Client
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
|
||||
private static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);
|
||||
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
|
@ -50,47 +50,54 @@ namespace RageCoop.Client
|
||||
flags |= VehicleDataFlags.IsHornActive;
|
||||
}
|
||||
|
||||
if (v.IsSubmarineCar && Function.Call<bool>(Hash._GET_IS_SUBMARINE_VEHICLE_TRANSFORMED, veh.Handle))
|
||||
if (v.IsSubmarineCar && Function.Call<bool>(Hash.IS_VEHICLE_IN_SUBMARINE_MODE, veh.Handle))
|
||||
{
|
||||
flags |= VehicleDataFlags.IsTransformed;
|
||||
}
|
||||
|
||||
if (v.IsAircraft)
|
||||
{
|
||||
flags |= VehicleDataFlags.IsAircraft;
|
||||
}
|
||||
|
||||
if (v.IsDeluxo && veh.IsDeluxoHovering())
|
||||
{
|
||||
flags |= VehicleDataFlags.IsDeluxoHovering;
|
||||
}
|
||||
|
||||
if (v.HasRoof)
|
||||
{
|
||||
flags |= VehicleDataFlags.HasRoof;
|
||||
}
|
||||
|
||||
if (v.HasRocketBoost && veh.IsRocketBoostActive())
|
||||
{
|
||||
flags |= VehicleDataFlags.IsRocketBoostActive;
|
||||
}
|
||||
if(v.HasParachute && veh.IsParachuteActive()){
|
||||
|
||||
if (v.HasParachute && veh.IsParachuteActive())
|
||||
{
|
||||
flags |= VehicleDataFlags.IsParachuteActive;
|
||||
}
|
||||
|
||||
if (veh.IsOnFire)
|
||||
{
|
||||
flags |= VehicleDataFlags.IsOnFire;
|
||||
}
|
||||
|
||||
|
||||
return flags;
|
||||
}
|
||||
public static bool IsRocketBoostActive(this Vehicle veh)
|
||||
{
|
||||
return Function.Call<bool>(Hash._IS_VEHICLE_ROCKET_BOOST_ACTIVE,veh);
|
||||
return Function.Call<bool>(Hash.IS_ROCKET_BOOST_ACTIVE, veh);
|
||||
}
|
||||
public static bool IsParachuteActive(this Vehicle veh){
|
||||
public static bool IsParachuteActive(this Vehicle veh)
|
||||
{
|
||||
return Function.Call<bool>((Hash)0x3DE51E9C80B116CF, veh);
|
||||
}
|
||||
public static void SetRocketBoostActive(this Vehicle veh, bool toggle)
|
||||
{
|
||||
Function.Call(Hash._SET_VEHICLE_ROCKET_BOOST_ACTIVE,veh,toggle);
|
||||
Function.Call(Hash.SET_ROCKET_BOOST_ACTIVE, veh, toggle);
|
||||
}
|
||||
public static void SetParachuteActive(this Vehicle veh, bool toggle)
|
||||
{
|
||||
@ -133,7 +140,6 @@ namespace RageCoop.Client
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Bursted tires
|
||||
short burstedTires = 0;
|
||||
foreach (VehicleWheel wheel in veh.Wheels.GetAllWheels())
|
||||
@ -228,16 +234,15 @@ namespace RageCoop.Client
|
||||
{
|
||||
if (p.IsSittingInVehicle())
|
||||
{
|
||||
ps.Add((int)p.SeatIndex, (int)p.GetSyncEntity().ID);
|
||||
ps.Add((int)p.SeatIndex, p.GetSyncEntity().ID);
|
||||
}
|
||||
}
|
||||
return ps;
|
||||
}
|
||||
|
||||
|
||||
public static void SetDeluxoHoverState(this Vehicle deluxo, bool hover)
|
||||
{
|
||||
Function.Call(Hash._SET_VEHICLE_HOVER_TRANSFORM_PERCENTAGE, deluxo, hover ? 1f : 0f);
|
||||
Function.Call(Hash.SET_SPECIAL_FLIGHT_MODE_TARGET_RATIO, deluxo, hover ? 1f : 0f);
|
||||
}
|
||||
public static bool IsDeluxoHovering(this Vehicle deluxo)
|
||||
{
|
||||
@ -245,7 +250,7 @@ namespace RageCoop.Client
|
||||
}
|
||||
public static void SetDeluxoWingRatio(this Vehicle v, float ratio)
|
||||
{
|
||||
Function.Call(Hash._SET_SPECIALFLIGHT_WING_RATIO, v, ratio);
|
||||
Function.Call(Hash.SET_HOVER_MODE_WING_RATIO, v, ratio);
|
||||
}
|
||||
public static float GetDeluxoWingRatio(this Vehicle v)
|
||||
{
|
||||
@ -253,7 +258,7 @@ namespace RageCoop.Client
|
||||
}
|
||||
public static float GetNozzleAngel(this Vehicle plane)
|
||||
{
|
||||
return Function.Call<float>(Hash._GET_VEHICLE_FLIGHT_NOZZLE_POSITION, plane);
|
||||
return Function.Call<float>(Hash.GET_VEHICLE_FLIGHT_NOZZLE_POSITION, plane);
|
||||
}
|
||||
public static bool HasNozzle(this Vehicle v)
|
||||
{
|
||||
@ -283,8 +288,6 @@ namespace RageCoop.Client
|
||||
{
|
||||
Function.Call(Hash.SET_VEHICLE_FLIGHT_NOZZLE_POSITION, plane, ratio);
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
using GTA.Math;
|
||||
using GTA.Native;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -46,7 +45,8 @@ namespace RageCoop.Client
|
||||
}
|
||||
return p.Bones[Bone.SkelRightHand].Position;
|
||||
}
|
||||
static long BulletsShot = 0;
|
||||
|
||||
private static long BulletsShot = 0;
|
||||
|
||||
public static float GetWeaponDamage(this Ped P, uint hash)
|
||||
{
|
||||
@ -362,7 +362,7 @@ namespace RageCoop.Client
|
||||
return 30;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
return AddOnDataProvider.GetMuzzleIndex(v.Model.Hash);
|
||||
}
|
||||
}
|
||||
public static bool IsUsingProjectileWeapon(this Ped p)
|
||||
@ -371,18 +371,12 @@ namespace RageCoop.Client
|
||||
var type = Function.Call<int>(Hash.GET_WEAPON_DAMAGE_TYPE, vp);
|
||||
if (vp != VehicleWeaponHash.Invalid)
|
||||
{
|
||||
if (type==3)
|
||||
{
|
||||
return false;
|
||||
return type == 3 ? false : VehicleProjectileWeapons.Contains(vp) || (type == 5 && !ExplosiveBullets.Contains((uint)vp));
|
||||
}
|
||||
return VehicleProjectileWeapons.Contains(vp) || (type==5 && !ExplosiveBullets.Contains((uint)vp));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
var w = p.Weapons.Current;
|
||||
return w.Group == WeaponGroup.Thrown || ProjectileWeapons.Contains(w.Hash);
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly HashSet<uint> ExplosiveBullets = new HashSet<uint>
|
||||
{
|
||||
@ -460,7 +454,6 @@ namespace RageCoop.Client
|
||||
|
||||
};
|
||||
|
||||
|
||||
public static readonly HashSet<WeaponHash> ProjectileWeapons = new HashSet<WeaponHash> {
|
||||
WeaponHash.HomingLauncher,
|
||||
WeaponHash.RPG,
|
||||
|
@ -1,8 +1,6 @@
|
||||
using GTA;
|
||||
using GTA.Native;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Threading;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -22,28 +20,11 @@ namespace RageCoop.Client
|
||||
{
|
||||
ChangeTraffic(true);
|
||||
};
|
||||
Task.Run(() =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Thread.Sleep(5000);
|
||||
Main.QueueAction(() => { ChangeTraffic(_trafficEnabled); });
|
||||
}
|
||||
});
|
||||
}
|
||||
static bool _trafficEnabled;
|
||||
|
||||
private static bool _trafficEnabled;
|
||||
private void OnTick(object sender, EventArgs e)
|
||||
{
|
||||
if (!_trafficEnabled)
|
||||
{
|
||||
Function.Call(Hash.SET_VEHICLE_POPULATION_BUDGET, 0);
|
||||
Function.Call(Hash.SET_PED_POPULATION_BUDGET, 0);
|
||||
Function.Call(Hash.SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME, 0f);
|
||||
Function.Call(Hash.SET_RANDOM_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME, 0f);
|
||||
Function.Call(Hash.SET_PARKED_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME, 0f);
|
||||
Function.Call(Hash.SUPPRESS_SHOCKING_EVENTS_NEXT_FRAME);
|
||||
Function.Call(Hash.SUPPRESS_AGITATION_EVENTS_NEXT_FRAME);
|
||||
}
|
||||
if (Game.IsLoading || !Networking.IsOnServer)
|
||||
{
|
||||
return;
|
||||
@ -84,6 +65,16 @@ namespace RageCoop.Client
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!_trafficEnabled)
|
||||
{
|
||||
Function.Call(Hash.SET_VEHICLE_POPULATION_BUDGET, 0);
|
||||
Function.Call(Hash.SET_PED_POPULATION_BUDGET, 0);
|
||||
Function.Call(Hash.SET_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME, 0f);
|
||||
Function.Call(Hash.SET_RANDOM_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME, 0f);
|
||||
Function.Call(Hash.SET_PARKED_VEHICLE_DENSITY_MULTIPLIER_THIS_FRAME, 0f);
|
||||
Function.Call(Hash.SUPPRESS_SHOCKING_EVENTS_NEXT_FRAME);
|
||||
Function.Call(Hash.SUPPRESS_AGITATION_EVENTS_NEXT_FRAME);
|
||||
}
|
||||
}
|
||||
public static void Traffic(bool enable)
|
||||
{
|
||||
@ -94,7 +85,7 @@ namespace RageCoop.Client
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
// Function.Call(Hash.REMOVE_SCENARIO_BLOCKING_AREAS);
|
||||
Function.Call(Hash.REMOVE_SCENARIO_BLOCKING_AREAS);
|
||||
Function.Call(Hash.SET_CREATE_RANDOM_COPS, true);
|
||||
Function.Call(Hash.SET_RANDOM_TRAINS, true);
|
||||
Function.Call(Hash.SET_RANDOM_BOATS, true);
|
||||
@ -107,9 +98,9 @@ namespace RageCoop.Client
|
||||
Function.Call(Hash.SET_DISTANT_CARS_ENABLED, true);
|
||||
Function.Call(Hash.DISABLE_VEHICLE_DISTANTLIGHTS, false);
|
||||
}
|
||||
else
|
||||
else if (Networking.IsOnServer)
|
||||
{
|
||||
// Function.Call(Hash.ADD_SCENARIO_BLOCKING_AREA, -10000.0f, -10000.0f, -1000.0f, 10000.0f, 10000.0f, 1000.0f, 0, 1, 1, 1);
|
||||
Function.Call(Hash.ADD_SCENARIO_BLOCKING_AREA, -10000.0f, -10000.0f, -1000.0f, 10000.0f, 10000.0f, 1000.0f, 0, 1, 1, 1);
|
||||
Function.Call(Hash.SET_CREATE_RANDOM_COPS, false);
|
||||
Function.Call(Hash.SET_RANDOM_TRAINS, false);
|
||||
Function.Call(Hash.SET_RANDOM_BOATS, false);
|
||||
@ -122,29 +113,24 @@ namespace RageCoop.Client
|
||||
Function.Call(Hash.SET_NUMBER_OF_PARKED_VEHICLES, 0);
|
||||
Function.Call(Hash.SET_DISTANT_CARS_ENABLED, false);
|
||||
Function.Call(Hash.DISABLE_VEHICLE_DISTANTLIGHTS, true);
|
||||
|
||||
if (Networking.IsOnServer)
|
||||
{
|
||||
|
||||
foreach (Ped ped in World.GetAllPeds())
|
||||
{
|
||||
if (ped == Game.Player.Character) { continue; }
|
||||
SyncedPed c = EntityPool.GetPedByHandle(ped.Handle);
|
||||
if ((c == null) || (c.IsLocal && (ped.Handle != Game.Player.Character.Handle) && ped.PopulationType != EntityPopulationType.Mission))
|
||||
{
|
||||
if (ped.Handle == Game.Player.Character.Handle) { continue; }
|
||||
|
||||
// Main.Logger.Trace($"Removing ped {ped.Handle}. Reason:RemoveTraffic");
|
||||
Main.Logger.Trace($"Removing ped {ped.Handle}. Reason:RemoveTraffic");
|
||||
ped.CurrentVehicle?.Delete();
|
||||
ped.Kill();
|
||||
ped.Delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach (Vehicle veh in World.GetAllVehicles())
|
||||
{
|
||||
SyncedVehicle v = veh.GetSyncEntity();
|
||||
if (v.MainVehicle == Game.Player.LastVehicle)
|
||||
if (v.MainVehicle == Game.Player.LastVehicle || v.MainVehicle == Game.Player.Character.CurrentVehicle)
|
||||
{
|
||||
// Don't delete player's vehicle
|
||||
continue;
|
||||
@ -157,32 +143,6 @@ namespace RageCoop.Client
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (Ped ped in World.GetAllPeds())
|
||||
{
|
||||
if ((ped != Game.Player.Character) && (ped.PopulationType != EntityPopulationType.Mission))
|
||||
{
|
||||
// Main.Logger.Trace($"Removing ped {ped.Handle}. Reason:RemoveTraffic");
|
||||
ped.CurrentVehicle?.Delete();
|
||||
ped.Kill();
|
||||
ped.Delete();
|
||||
}
|
||||
|
||||
}
|
||||
var last = Game.Player.Character.LastVehicle;
|
||||
var current = Game.Player.Character.CurrentVehicle;
|
||||
foreach (Vehicle veh in World.GetAllVehicles())
|
||||
{
|
||||
if (veh.PopulationType != EntityPopulationType.Mission && veh != last && veh!=current)
|
||||
{
|
||||
// Main.Logger.Debug($"Removing Vehicle {veh.Handle}. Reason:ClearTraffic");
|
||||
|
||||
veh.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using GTA.Math;
|
||||
using GTA.Math;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
|
@ -1,17 +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;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.NetworkInformation;
|
||||
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")]
|
||||
@ -33,43 +34,44 @@ namespace RageCoop.Core
|
||||
{
|
||||
return ToIgnore.Contains(name);
|
||||
}
|
||||
public static (byte, byte[]) GetBytesFromObject(object obj)
|
||||
public static void GetBytesFromObject(object obj, NetOutgoingMessage m)
|
||||
{
|
||||
switch (obj)
|
||||
{
|
||||
case byte _:
|
||||
return (0x01, new byte[] { (byte)obj });
|
||||
case short _:
|
||||
return (0x02, BitConverter.GetBytes((short)obj));
|
||||
case ushort _:
|
||||
return (0x03, BitConverter.GetBytes((ushort)obj));
|
||||
case int _:
|
||||
return (0x04, BitConverter.GetBytes((int)obj));
|
||||
case uint _:
|
||||
return (0x05, BitConverter.GetBytes((uint)obj));
|
||||
case long _:
|
||||
return (0x06, BitConverter.GetBytes((long)obj));
|
||||
case ulong _:
|
||||
return (0x07, BitConverter.GetBytes((ulong)obj));
|
||||
case float _:
|
||||
return (0x08, BitConverter.GetBytes((float)obj));
|
||||
case bool _:
|
||||
return (0x09, BitConverter.GetBytes((bool)obj));
|
||||
case string _:
|
||||
return (0x10, ((string)obj).GetBytesWithLength());
|
||||
case Vector3 _:
|
||||
return (0x11,((Vector3)obj).GetBytes());
|
||||
case Quaternion _:
|
||||
return (0x12, ((Quaternion)obj).GetBytes());
|
||||
case GTA.Model _:
|
||||
return (0x13, BitConverter.GetBytes((GTA.Model)obj));
|
||||
case Vector2 _:
|
||||
return (0x14, ((Vector2)obj).GetBytes());
|
||||
case Tuple<byte, byte[]> _:
|
||||
var tup = (Tuple<byte, byte[]>)obj;
|
||||
return (tup.Item1, tup.Item2);
|
||||
case byte value:
|
||||
m.Write((byte)0x01); m.Write(value); break;
|
||||
case short value:
|
||||
m.Write((byte)0x02); m.Write(value); break;
|
||||
case ushort value:
|
||||
m.Write((byte)0x03); m.Write(value); break;
|
||||
case int value:
|
||||
m.Write((byte)0x04); m.Write(value); break;
|
||||
case uint value:
|
||||
m.Write((byte)0x05); m.Write(value); break;
|
||||
case long value:
|
||||
m.Write((byte)0x06); m.Write(value); break;
|
||||
case ulong value:
|
||||
m.Write((byte)0x07); m.Write(value); break;
|
||||
case float value:
|
||||
m.Write((byte)0x08); m.Write(value); break;
|
||||
case bool value:
|
||||
m.Write((byte)0x09); m.Write(value); break;
|
||||
case string value:
|
||||
m.Write((byte)0x10); m.Write(value); break;
|
||||
case Vector3 value:
|
||||
m.Write((byte)0x11); m.Write(value); break;
|
||||
case Quaternion value:
|
||||
m.Write((byte)0x12); m.Write(value); break;
|
||||
case GTA.Model value:
|
||||
m.Write((byte)0x13); m.Write(value); break;
|
||||
case Vector2 value:
|
||||
m.Write((byte)0x14); m.Write(value); break;
|
||||
case byte[] value:
|
||||
m.Write((byte)0x15); m.WriteByteArray(value); break;
|
||||
case Tuple<byte, byte[]> value:
|
||||
m.Write(value.Item1); m.Write(value.Item2); break;
|
||||
default:
|
||||
return (0x0, null);
|
||||
throw new Exception("Unsupported object type: " + obj.GetType());
|
||||
}
|
||||
}
|
||||
public static IPEndPoint StringToEndPoint(string endpointstring)
|
||||
@ -136,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)
|
||||
{
|
||||
@ -190,7 +191,40 @@ namespace RageCoop.Core
|
||||
foreach (FileInfo file in source.GetFiles())
|
||||
file.CopyTo(Path.Combine(target.FullName, file.Name), true);
|
||||
}
|
||||
public static string GetInvariantRID()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
return "win-" + RuntimeInformation.OSArchitecture.ToString().ToLower();
|
||||
}
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
return "linux-" + RuntimeInformation.OSArchitecture.ToString().ToLower();
|
||||
}
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
return "osx-" + RuntimeInformation.OSArchitecture.ToString().ToLower();
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get local ip addresses on all network interfaces
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static List<IPAddress> GetLocalAddress()
|
||||
{
|
||||
var addresses = new List<IPAddress>();
|
||||
foreach (NetworkInterface netInterface in NetworkInterface.GetAllNetworkInterfaces())
|
||||
{
|
||||
IPInterfaceProperties ipProps = netInterface.GetIPProperties();
|
||||
foreach (UnicastIPAddressInformation addr in ipProps.UnicastAddresses)
|
||||
{
|
||||
addresses.Add(addr.Address);
|
||||
}
|
||||
}
|
||||
return addresses;
|
||||
}
|
||||
}
|
||||
internal class IpInfo
|
||||
{
|
||||
@ -202,74 +236,10 @@ namespace RageCoop.Core
|
||||
}
|
||||
internal static class Extensions
|
||||
{
|
||||
public static void AddVector3(this List<byte> bytes, Vector3 vec3)
|
||||
{
|
||||
bytes.AddRange(BitConverter.GetBytes(vec3.X));
|
||||
bytes.AddRange(BitConverter.GetBytes(vec3.Y));
|
||||
bytes.AddRange(BitConverter.GetBytes(vec3.Z));
|
||||
}
|
||||
public static void AddQuaternion(this List<byte> bytes, Quaternion quat)
|
||||
{
|
||||
bytes.AddRange(BitConverter.GetBytes(quat.X));
|
||||
bytes.AddRange(BitConverter.GetBytes(quat.Y));
|
||||
bytes.AddRange(BitConverter.GetBytes(quat.Z));
|
||||
bytes.AddRange(BitConverter.GetBytes(quat.W));
|
||||
}
|
||||
public static void AddInt(this List<byte> bytes,int i)
|
||||
{
|
||||
bytes.AddRange(BitConverter.GetBytes(i));
|
||||
}
|
||||
public static void AddUint(this List<byte> bytes, uint i)
|
||||
{
|
||||
bytes.AddRange(BitConverter.GetBytes(i));
|
||||
}
|
||||
public static void AddShort(this List<byte> bytes, short i)
|
||||
{
|
||||
bytes.AddRange(BitConverter.GetBytes(i));
|
||||
}
|
||||
public static void AddUshort(this List<byte> bytes, ushort i)
|
||||
{
|
||||
bytes.AddRange(BitConverter.GetBytes(i));
|
||||
}
|
||||
public static void AddLong(this List<byte> bytes, long i)
|
||||
{
|
||||
bytes.AddRange(BitConverter.GetBytes(i));
|
||||
}
|
||||
public static void AddUlong(this List<byte> bytes, ulong i)
|
||||
{
|
||||
bytes.AddRange(BitConverter.GetBytes(i));
|
||||
}
|
||||
public static void AddFloat(this List<byte> bytes, float i)
|
||||
{
|
||||
bytes.AddRange(BitConverter.GetBytes(i));
|
||||
}
|
||||
public static void AddBool(this List<byte> bytes, bool b)
|
||||
{
|
||||
bytes.Add(b? (byte)1 :(byte)0);
|
||||
}
|
||||
public static void AddString(this List<byte> bytes, string s)
|
||||
{
|
||||
var sb = Encoding.UTF8.GetBytes(s);
|
||||
bytes.AddInt(sb.Length);
|
||||
bytes.AddRange(sb);
|
||||
}
|
||||
public static void AddArray(this List<byte> bytes, byte[] toadd)
|
||||
{
|
||||
bytes.AddInt(toadd.Length);
|
||||
bytes.AddRange(toadd);
|
||||
}
|
||||
public static byte[] GetBytes(this string s)
|
||||
{
|
||||
return Encoding.UTF8.GetBytes(s);
|
||||
}
|
||||
public static byte[] GetBytesWithLength(this string s)
|
||||
{
|
||||
var data = new List<byte>(100);
|
||||
var sb = Encoding.UTF8.GetBytes(s);
|
||||
data.AddInt(sb.Length);
|
||||
data.AddRange(sb);
|
||||
return data.ToArray();
|
||||
}
|
||||
public static string GetString(this byte[] data)
|
||||
{
|
||||
return Encoding.UTF8.GetString(data);
|
||||
@ -296,17 +266,10 @@ 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, T existingPacket = null) where T : Packet, new()
|
||||
public static T GetPacket<T>(this NetIncomingMessage msg) where T : Packet, new()
|
||||
{
|
||||
msg.ReadByte();
|
||||
return GetPacket<T>(msg.ReadBytes(msg.ReadInt32()),existingPacket);
|
||||
}
|
||||
public static T GetPacket<T>(this byte[] data, T existingPacket=null) where T : Packet, new()
|
||||
{
|
||||
var p = existingPacket??new T();
|
||||
p.Deserialize(data);
|
||||
var p = new T();
|
||||
p.Deserialize(msg);
|
||||
return p;
|
||||
}
|
||||
public static bool HasPedFlag(this PedDataFlags flagToCheck, PedDataFlags flag)
|
||||
@ -399,7 +362,7 @@ namespace RageCoop.Core
|
||||
}
|
||||
public static string Dump<T>(this IEnumerable<T> objects)
|
||||
{
|
||||
return "{"+string.Join(",",objects)+"}";
|
||||
return $"{{{string.Join(",", objects)}}}";
|
||||
}
|
||||
public static void ForEach<T>(this IEnumerable<T> objects, Action<T> action)
|
||||
{
|
||||
@ -482,5 +445,6 @@ namespace RageCoop.Core
|
||||
{
|
||||
return IPAddress.Parse(ip);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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,9 +31,9 @@ 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)
|
||||
{
|
||||
|
@ -1,9 +1,8 @@
|
||||
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;
|
||||
@ -82,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,
|
||||
@ -146,16 +145,12 @@ namespace RageCoop.Core
|
||||
}
|
||||
private static float CopySign(double x, double y)
|
||||
{
|
||||
bool isPositive = y>=0;
|
||||
if (isPositive)
|
||||
if (y >= 0)
|
||||
{
|
||||
if (x>=0) { return (float)x; } else { return (float)-x; }
|
||||
return x >= 0 ? (float)x : (float)-x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x>=0) { return (float)-x; } else { return (float)x; }
|
||||
|
||||
}
|
||||
return x >= 0 ? (float)-x : (float)x;
|
||||
}
|
||||
public static double AngelTo(this Vector3 v1, Vector3 v2)
|
||||
{
|
||||
@ -163,7 +158,6 @@ namespace RageCoop.Core
|
||||
}
|
||||
public static float GetCosTheta(this Vector3 v1, Vector3 v2)
|
||||
{
|
||||
|
||||
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
|
||||
@ -57,6 +56,5 @@ namespace RageCoop.Core
|
||||
p.Pack(outgoingMessage);
|
||||
SendMessage(outgoingMessage, cons, method, (int)channel);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
@ -32,7 +30,9 @@ namespace RageCoop.Core
|
||||
{
|
||||
// TLS only
|
||||
ServicePointManager.Expect100Continue = true;
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 |
|
||||
SecurityProtocolType.Tls11 |
|
||||
SecurityProtocolType.Tls;
|
||||
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
|
||||
|
||||
WebClient client = new WebClient();
|
||||
|
@ -1,17 +1,17 @@
|
||||
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{
|
||||
public static PublicKey FromServerInfo(ServerInfo info)
|
||||
{
|
||||
return new PublicKey
|
||||
{
|
||||
Modulus = Convert.FromBase64String(info.publicKeyModulus),
|
||||
Exponent = Convert.FromBase64String(info.publicKeyExponent)
|
||||
};
|
||||
|
@ -1,13 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace RageCoop.Core
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
|
||||
internal class ServerInfo
|
||||
/// <summary>
|
||||
/// A json object representing a server's information as annouced to master server.
|
||||
/// </summary>
|
||||
public class ServerInfo
|
||||
{
|
||||
#pragma warning disable 1591
|
||||
public string address { get; set; }
|
||||
public string port { get; set; }
|
||||
public string name { 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
|
||||
@ -93,7 +91,8 @@ namespace RageCoop.Core
|
||||
}
|
||||
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);
|
||||
|
71
RageCoop.Core/PacketExtensions.cs
Normal file
71
RageCoop.Core/PacketExtensions.cs
Normal file
@ -0,0 +1,71 @@
|
||||
using GTA.Math;
|
||||
using Lidgren.Network;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
internal static class PacketExtensions
|
||||
{
|
||||
#region MESSAGE-READ
|
||||
public static Vector3 ReadVector3(this NetIncomingMessage m)
|
||||
{
|
||||
return new Vector3
|
||||
{
|
||||
X = m.ReadFloat(),
|
||||
Y = m.ReadFloat(),
|
||||
Z = m.ReadFloat(),
|
||||
};
|
||||
}
|
||||
public static Vector2 ReadVector2(this NetIncomingMessage m)
|
||||
{
|
||||
return new Vector2
|
||||
{
|
||||
X = m.ReadFloat(),
|
||||
Y = m.ReadFloat(),
|
||||
};
|
||||
}
|
||||
public static Quaternion ReadQuaternion(this NetIncomingMessage m)
|
||||
{
|
||||
return new Quaternion
|
||||
{
|
||||
X = m.ReadFloat(),
|
||||
Y = m.ReadFloat(),
|
||||
Z = m.ReadFloat(),
|
||||
W = m.ReadFloat(),
|
||||
};
|
||||
}
|
||||
public static byte[] ReadByteArray(this NetIncomingMessage m)
|
||||
{
|
||||
return m.ReadBytes(m.ReadInt32());
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region MESSAGE-WRITE
|
||||
public static void Write(this NetOutgoingMessage m, Vector3 v)
|
||||
{
|
||||
m.Write(v.X);
|
||||
m.Write(v.Y);
|
||||
m.Write(v.Z);
|
||||
}
|
||||
public static void Write(this NetOutgoingMessage m, Quaternion q)
|
||||
{
|
||||
m.Write(q.X);
|
||||
m.Write(q.Y);
|
||||
m.Write(q.Z);
|
||||
m.Write(q.W);
|
||||
}
|
||||
public static void WriteByteArray(this NetOutgoingMessage m, byte[] b)
|
||||
{
|
||||
m.Write(b.Length);
|
||||
m.Write(b);
|
||||
}
|
||||
#endregion
|
||||
|
||||
internal static bool IsSyncEvent(this PacketType p)
|
||||
{
|
||||
return (30 <= (byte)p) && ((byte)p <= 40);
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
@ -25,33 +24,31 @@ namespace RageCoop.Core
|
||||
|
||||
public string Message { get; set; }
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
|
||||
|
||||
|
||||
// Write Username
|
||||
byteArray.AddString(Username);
|
||||
m.Write(Username);
|
||||
|
||||
|
||||
// Write Message
|
||||
byteArray.AddArray(crypt(Message));
|
||||
|
||||
return byteArray.ToArray();
|
||||
m.WriteByteArray(crypt(Message));
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
|
||||
// Read username
|
||||
Username = reader.ReadString();
|
||||
Username = m.ReadString();
|
||||
|
||||
Message = decrypt(reader.ReadByteArray()).GetString();
|
||||
Message = decrypt(m.ReadByteArray()).GetString();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -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,85 +8,78 @@ namespace RageCoop.Core
|
||||
internal class CustomEvent : Packet
|
||||
{
|
||||
public override PacketType Type => (_queued ? PacketType.CustomEventQueued : PacketType.CustomEvent);
|
||||
public CustomEvent(Func<byte,BitReader,object> onResolve = null,bool queued=false)
|
||||
public CustomEvent(Func<byte, NetIncomingMessage, object> onResolve = null, bool queued = false)
|
||||
{
|
||||
_resolve = onResolve;
|
||||
_queued = queued;
|
||||
}
|
||||
private bool _queued;
|
||||
private Func<byte, BitReader, object> _resolve { get; set; }
|
||||
private readonly bool _queued;
|
||||
private Func<byte, NetIncomingMessage, object> _resolve { get; set; }
|
||||
public int Hash { get; set; }
|
||||
public object[] Args { get; set; }
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
Args = Args ?? new object[] { };
|
||||
|
||||
List<byte> result = new List<byte>();
|
||||
result.AddInt(Hash);
|
||||
result.AddInt(Args.Length);
|
||||
(byte, byte[]) tup;
|
||||
m.Write(Hash);
|
||||
m.Write(Args.Length);
|
||||
foreach (var arg in Args)
|
||||
{
|
||||
tup=CoreUtils.GetBytesFromObject(arg);
|
||||
if (tup.Item1==0||tup.Item2==null)
|
||||
{
|
||||
throw new ArgumentException($"Object of type {arg.GetType()} is not supported");
|
||||
CoreUtils.GetBytesFromObject(arg, m);
|
||||
}
|
||||
result.Add(tup.Item1);
|
||||
result.AddRange(tup.Item2);
|
||||
}
|
||||
return result.ToArray();
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
Hash = reader.ReadInt32();
|
||||
var len=reader.ReadInt32();
|
||||
|
||||
Hash = m.ReadInt32();
|
||||
var len = m.ReadInt32();
|
||||
Args = new object[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
byte type = reader.ReadByte();
|
||||
byte type = m.ReadByte();
|
||||
switch (type)
|
||||
{
|
||||
case 0x01:
|
||||
Args[i]=reader.ReadByte(); break;
|
||||
Args[i] = m.ReadByte(); break;
|
||||
case 0x02:
|
||||
Args[i]=reader.ReadInt32(); break;
|
||||
Args[i] = m.ReadInt32(); break;
|
||||
case 0x03:
|
||||
Args[i]=reader.ReadUInt16(); break;
|
||||
Args[i] = m.ReadUInt16(); break;
|
||||
case 0x04:
|
||||
Args[i]=reader.ReadInt32(); break;
|
||||
Args[i] = m.ReadInt32(); break;
|
||||
case 0x05:
|
||||
Args[i]=reader.ReadUInt32(); break;
|
||||
Args[i] = m.ReadUInt32(); break;
|
||||
case 0x06:
|
||||
Args[i]=reader.ReadInt64(); break;
|
||||
Args[i] = m.ReadInt64(); break;
|
||||
case 0x07:
|
||||
Args[i]=reader.ReadUInt64(); break;
|
||||
Args[i] = m.ReadUInt64(); break;
|
||||
case 0x08:
|
||||
Args[i]=reader.ReadSingle(); break;
|
||||
Args[i] = m.ReadFloat(); break;
|
||||
case 0x09:
|
||||
Args[i]=reader.ReadBoolean(); break;
|
||||
Args[i] = m.ReadBoolean(); break;
|
||||
case 0x10:
|
||||
Args[i]=reader.ReadString(); break;
|
||||
Args[i] = m.ReadString(); break;
|
||||
case 0x11:
|
||||
Args[i]=reader.ReadVector3(); break;
|
||||
Args[i] = m.ReadVector3(); break;
|
||||
case 0x12:
|
||||
Args[i]=reader.ReadQuaternion(); break;
|
||||
Args[i] = m.ReadQuaternion(); break;
|
||||
case 0x13:
|
||||
Args[i]=(GTA.Model)reader.ReadInt32(); break;
|
||||
Args[i] = (GTA.Model)m.ReadInt32(); break;
|
||||
case 0x14:
|
||||
Args[i]=reader.ReadVector2(); break;
|
||||
Args[i] = m.ReadVector2(); break;
|
||||
case 0x15:
|
||||
Args[i] = m.ReadByteArray(); break;
|
||||
default:
|
||||
if (_resolve == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Unexpected type:{type}\r\n{array.Dump()}");
|
||||
throw new InvalidOperationException($"Unexpected type: {type}");
|
||||
}
|
||||
else
|
||||
{
|
||||
Args[i]=_resolve(type, reader); break;
|
||||
Args[i] = _resolve(type, m); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
@ -25,34 +22,30 @@ namespace RageCoop.Core
|
||||
|
||||
public long FileLength { get; set; }
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
|
||||
// The ID from the download
|
||||
byteArray.AddInt(ID);
|
||||
m.Write(ID);
|
||||
|
||||
|
||||
// The name of the file
|
||||
byte[] nameBytes = Encoding.UTF8.GetBytes(Name);
|
||||
byteArray.AddRange(BitConverter.GetBytes(nameBytes.Length));
|
||||
byteArray.AddRange(nameBytes);
|
||||
m.Write(Name);
|
||||
|
||||
// The length of the file
|
||||
byteArray.AddRange(BitConverter.GetBytes(FileLength));
|
||||
|
||||
return byteArray.ToArray();
|
||||
m.Write(FileLength);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
ID = reader.ReadInt32();
|
||||
Name = reader.ReadString();
|
||||
FileLength = reader.ReadInt64();
|
||||
|
||||
ID = m.ReadInt32();
|
||||
Name = m.ReadString();
|
||||
FileLength = m.ReadInt64();
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,25 +54,21 @@ namespace RageCoop.Core
|
||||
public override PacketType Type => PacketType.FileTransferResponse;
|
||||
public int ID { get; set; }
|
||||
public FileResponse Response { get; set; }
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
// The ID from the download
|
||||
byteArray.AddInt(ID);
|
||||
m.Write(ID);
|
||||
|
||||
byteArray.Add((byte)Response);
|
||||
m.Write((byte)Response);
|
||||
|
||||
return byteArray.ToArray();
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
ID = reader.ReadInt32();
|
||||
Response = (FileResponse)reader.ReadByte();
|
||||
ID = m.ReadInt32();
|
||||
Response = (FileResponse)m.ReadByte();
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,27 +79,21 @@ namespace RageCoop.Core
|
||||
|
||||
public byte[] FileChunk { get; set; }
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
|
||||
// The ID from the download
|
||||
byteArray.AddInt(ID);
|
||||
|
||||
// The chunk of the file
|
||||
byteArray.AddInt(FileChunk.Length);
|
||||
byteArray.AddRange(FileChunk);
|
||||
|
||||
return byteArray.ToArray();
|
||||
m.Write(ID);
|
||||
m.WriteByteArray(FileChunk);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
ID = reader.ReadInt32();
|
||||
FileChunk = reader.ReadByteArray();
|
||||
ID = m.ReadInt32();
|
||||
FileChunk = m.ReadByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,22 +102,20 @@ namespace RageCoop.Core
|
||||
public override PacketType Type => PacketType.FileTransferComplete;
|
||||
public int ID { get; set; }
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
|
||||
// The ID for the download
|
||||
byteArray.AddInt(ID);
|
||||
|
||||
return byteArray.ToArray();
|
||||
m.Write(ID);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
ID = reader.ReadInt32();
|
||||
|
||||
ID = m.ReadInt32();
|
||||
}
|
||||
}
|
||||
internal class AllResourcesSent : Packet
|
||||
|
@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Lidgren.Network;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
@ -14,26 +12,26 @@ namespace RageCoop.Core
|
||||
public string TargetInternal { get; set; }
|
||||
public string TargetExternal { get; set; }
|
||||
public bool Connect { get; set; }
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
byteArray.AddInt(TargetID);
|
||||
byteArray.AddString(TargetInternal);
|
||||
byteArray.AddString(TargetExternal);
|
||||
byteArray.AddBool(Connect);
|
||||
return byteArray.ToArray();
|
||||
|
||||
m.Write(TargetID);
|
||||
m.Write(TargetInternal);
|
||||
m.Write(TargetExternal);
|
||||
m.Write(Connect);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
TargetID = reader.ReadInt32();
|
||||
TargetInternal = reader.ReadString();
|
||||
TargetExternal = reader.ReadString();
|
||||
Connect=reader.ReadBoolean();
|
||||
|
||||
TargetID = m.ReadInt32();
|
||||
TargetInternal = m.ReadString();
|
||||
TargetExternal = m.ReadString();
|
||||
Connect = m.ReadBoolean();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -46,22 +44,22 @@ namespace RageCoop.Core
|
||||
/// 1:initial, 2:acknowledged, 3:confirmed
|
||||
/// </summary>
|
||||
public byte Status { get; set; }
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
byteArray.AddInt(Puncher);
|
||||
byteArray.Add(Status);
|
||||
return byteArray.ToArray();
|
||||
|
||||
m.Write(Puncher);
|
||||
m.Write(Status);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
Puncher = reader.ReadInt32();
|
||||
Status = reader.ReadByte();
|
||||
|
||||
Puncher = m.ReadInt32();
|
||||
Status = m.ReadByte();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using Lidgren.Network;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace RageCoop.Core
|
||||
@ -12,16 +12,15 @@ namespace RageCoop.Core
|
||||
{
|
||||
public int TargetID { get; set; }
|
||||
public override PacketType Type => PacketType.ConnectionRequest;
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
var data = new List<byte>(10);
|
||||
data.AddInt(TargetID);
|
||||
return data.ToArray();
|
||||
m.Write(TargetID);
|
||||
}
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
var reader=new BitReader(array);
|
||||
TargetID = reader.ReadInt32();
|
||||
|
||||
TargetID = m.ReadInt32();
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,16 +32,16 @@ namespace RageCoop.Core
|
||||
{
|
||||
public int ID { get; set; }
|
||||
public override PacketType Type => PacketType.P2PConnect;
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
var data = new List<byte>(10);
|
||||
data.AddInt(ID);
|
||||
return data.ToArray();
|
||||
m.Write(ID);
|
||||
|
||||
}
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
var reader = new BitReader(array);
|
||||
ID = reader.ReadInt32();
|
||||
|
||||
ID = m.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,5 @@
|
||||
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
|
||||
{
|
||||
@ -55,14 +51,6 @@ namespace RageCoop.Core
|
||||
|
||||
Unknown = 255
|
||||
}
|
||||
internal static class PacketExtensions
|
||||
{
|
||||
internal static bool IsSyncEvent(this PacketType p)
|
||||
{
|
||||
return (30<=(byte)p)&&((byte)p<=40);
|
||||
}
|
||||
}
|
||||
|
||||
internal enum ConnectionChannel
|
||||
{
|
||||
Default = 0,
|
||||
@ -153,25 +141,19 @@ namespace RageCoop.Core
|
||||
internal interface IPacket
|
||||
{
|
||||
PacketType Type { get; }
|
||||
byte[] Serialize();
|
||||
|
||||
void Deserialize(byte[] data);
|
||||
void Deserialize(NetIncomingMessage m);
|
||||
}
|
||||
|
||||
internal abstract class Packet : IPacket
|
||||
{
|
||||
public abstract PacketType Type { get; }
|
||||
public virtual byte[] Serialize()
|
||||
public void Pack(NetOutgoingMessage m)
|
||||
{
|
||||
return new byte[0];
|
||||
}
|
||||
public virtual void Deserialize(byte[] array) { }
|
||||
public void Pack(NetOutgoingMessage message)
|
||||
{
|
||||
var d=Serialize();
|
||||
message.Write((byte)Type);
|
||||
message.Write(d.Length);
|
||||
message.Write(d);
|
||||
m.Write((byte)Type);
|
||||
Serialize(m);
|
||||
}
|
||||
protected virtual void Serialize(NetOutgoingMessage m) { }
|
||||
public virtual void Deserialize(NetIncomingMessage m) { }
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
@ -61,92 +59,92 @@ namespace RageCoop.Core
|
||||
public float BlipScale { get; set; } = 1;
|
||||
#endregion
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
byteArray.AddInt(ID);
|
||||
byteArray.AddInt(OwnerID);
|
||||
byteArray.AddRange(BitConverter.GetBytes((ushort)Flags));
|
||||
byteArray.AddRange(BitConverter.GetBytes(Health));
|
||||
byteArray.Add(Speed);
|
||||
|
||||
m.Write(ID);
|
||||
m.Write(OwnerID);
|
||||
m.Write((ushort)Flags);
|
||||
m.Write(Health);
|
||||
m.Write(Speed);
|
||||
if (Flags.HasPedFlag(PedDataFlags.IsRagdoll))
|
||||
{
|
||||
byteArray.AddVector3(HeadPosition);
|
||||
byteArray.AddVector3(RightFootPosition);
|
||||
byteArray.AddVector3(LeftFootPosition);
|
||||
m.Write(HeadPosition);
|
||||
m.Write(RightFootPosition);
|
||||
m.Write(LeftFootPosition);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Speed >= 4)
|
||||
{
|
||||
byteArray.AddInt(VehicleID);
|
||||
byteArray.Add((byte)(Seat+3));
|
||||
m.Write(VehicleID);
|
||||
m.Write((byte)(Seat + 3));
|
||||
}
|
||||
byteArray.AddVector3(Position);
|
||||
m.Write(Position);
|
||||
}
|
||||
byteArray.AddVector3(Rotation);
|
||||
byteArray.AddVector3(Velocity);
|
||||
m.Write(Rotation);
|
||||
m.Write(Velocity);
|
||||
|
||||
|
||||
if (Flags.HasPedFlag(PedDataFlags.IsAiming))
|
||||
{
|
||||
byteArray.AddVector3(AimCoords);
|
||||
m.Write(AimCoords);
|
||||
}
|
||||
|
||||
byteArray.AddFloat(Heading);
|
||||
m.Write(Heading);
|
||||
|
||||
if (Flags.HasPedFlag(PedDataFlags.IsFullSync))
|
||||
{
|
||||
byteArray.AddInt(ModelHash);
|
||||
byteArray.AddUint(CurrentWeaponHash);
|
||||
byteArray.AddRange(Clothes);
|
||||
m.Write(ModelHash);
|
||||
m.Write(CurrentWeaponHash);
|
||||
m.Write(Clothes);
|
||||
if (WeaponComponents != null)
|
||||
{
|
||||
byteArray.Add(0x01);
|
||||
byteArray.AddRange(BitConverter.GetBytes((ushort)WeaponComponents.Count));
|
||||
m.Write(true);
|
||||
m.Write((ushort)WeaponComponents.Count);
|
||||
foreach (KeyValuePair<uint, bool> component in WeaponComponents)
|
||||
{
|
||||
byteArray.AddRange(BitConverter.GetBytes(component.Key));
|
||||
byteArray.AddRange(BitConverter.GetBytes(component.Value));
|
||||
m.Write(component.Key);
|
||||
m.Write(component.Value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Player weapon doesn't have any components
|
||||
byteArray.Add(0x00);
|
||||
m.Write(false);
|
||||
}
|
||||
|
||||
byteArray.Add(WeaponTint);
|
||||
m.Write(WeaponTint);
|
||||
|
||||
byteArray.Add((byte)BlipColor);
|
||||
m.Write((byte)BlipColor);
|
||||
if ((byte)BlipColor != 255)
|
||||
{
|
||||
byteArray.AddUshort((ushort)BlipSprite);
|
||||
byteArray.AddFloat(BlipScale);
|
||||
m.Write((ushort)BlipSprite);
|
||||
m.Write(BlipScale);
|
||||
}
|
||||
}
|
||||
|
||||
return byteArray.ToArray();
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
ID = reader.ReadInt32();
|
||||
OwnerID=reader.ReadInt32();
|
||||
Flags = (PedDataFlags)reader.ReadUInt16();
|
||||
Health = reader.ReadInt32();
|
||||
Speed = reader.ReadByte();
|
||||
|
||||
ID = m.ReadInt32();
|
||||
OwnerID = m.ReadInt32();
|
||||
Flags = (PedDataFlags)m.ReadUInt16();
|
||||
Health = m.ReadInt32();
|
||||
Speed = m.ReadByte();
|
||||
|
||||
if (Flags.HasPedFlag(PedDataFlags.IsRagdoll))
|
||||
{
|
||||
HeadPosition=reader.ReadVector3();
|
||||
RightFootPosition=reader.ReadVector3();
|
||||
LeftFootPosition=reader.ReadVector3();
|
||||
HeadPosition = m.ReadVector3();
|
||||
RightFootPosition = m.ReadVector3();
|
||||
LeftFootPosition = m.ReadVector3();
|
||||
Position = HeadPosition;
|
||||
}
|
||||
else
|
||||
@ -154,54 +152,54 @@ namespace RageCoop.Core
|
||||
// Vehicle related
|
||||
if (Speed >= 4)
|
||||
{
|
||||
VehicleID=reader.ReadInt32();
|
||||
Seat=(VehicleSeat)(reader.ReadByte()-3);
|
||||
VehicleID = m.ReadInt32();
|
||||
Seat = (VehicleSeat)(m.ReadByte() - 3);
|
||||
}
|
||||
|
||||
// Read player position
|
||||
Position = reader.ReadVector3();
|
||||
Position = m.ReadVector3();
|
||||
}
|
||||
|
||||
Rotation = reader.ReadVector3();
|
||||
Velocity = reader.ReadVector3();
|
||||
Rotation = m.ReadVector3();
|
||||
Velocity = m.ReadVector3();
|
||||
|
||||
if (Flags.HasPedFlag(PedDataFlags.IsAiming))
|
||||
{
|
||||
// Read player aim coords
|
||||
AimCoords = reader.ReadVector3();
|
||||
AimCoords = m.ReadVector3();
|
||||
}
|
||||
|
||||
Heading=reader.ReadSingle();
|
||||
Heading = m.ReadFloat();
|
||||
|
||||
if (Flags.HasPedFlag(PedDataFlags.IsFullSync))
|
||||
{
|
||||
// Read player model hash
|
||||
ModelHash = reader.ReadInt32();
|
||||
ModelHash = m.ReadInt32();
|
||||
|
||||
// Read player weapon hash
|
||||
CurrentWeaponHash = reader.ReadUInt32();
|
||||
CurrentWeaponHash = m.ReadUInt32();
|
||||
|
||||
// Read player clothes
|
||||
Clothes =reader.ReadBytes(36);
|
||||
Clothes = m.ReadBytes(36);
|
||||
|
||||
// Read player weapon components
|
||||
if (reader.ReadBoolean())
|
||||
if (m.ReadBoolean())
|
||||
{
|
||||
WeaponComponents = new Dictionary<uint, bool>();
|
||||
ushort comCount = reader.ReadUInt16();
|
||||
ushort comCount = m.ReadUInt16();
|
||||
for (ushort i = 0; i < comCount; i++)
|
||||
{
|
||||
WeaponComponents.Add(reader.ReadUInt32(), reader.ReadBoolean());
|
||||
WeaponComponents.Add(m.ReadUInt32(), m.ReadBoolean());
|
||||
}
|
||||
}
|
||||
WeaponTint=reader.ReadByte();
|
||||
WeaponTint = m.ReadByte();
|
||||
|
||||
BlipColor=(BlipColor)reader.ReadByte();
|
||||
BlipColor = (BlipColor)m.ReadByte();
|
||||
|
||||
if ((byte)BlipColor != 255)
|
||||
{
|
||||
BlipSprite=(BlipSprite)reader.ReadUInt16();
|
||||
BlipScale=reader.ReadSingle();
|
||||
BlipSprite = (BlipSprite)m.ReadUInt16();
|
||||
BlipScale = m.ReadFloat();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using GTA.Math;
|
||||
using GTA.Math;
|
||||
using Lidgren.Network;
|
||||
using System.Net;
|
||||
|
||||
namespace RageCoop.Core
|
||||
@ -38,62 +36,55 @@ namespace RageCoop.Core
|
||||
public byte[] PasswordEncrypted { get; set; }
|
||||
|
||||
public IPEndPoint InternalEndPoint { get; set; }
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
// Write Player Ped ID
|
||||
byteArray.AddRange(BitConverter.GetBytes(PedID));
|
||||
m.Write(PedID);
|
||||
|
||||
// Write Username
|
||||
byte[] usernameBytes = Encoding.UTF8.GetBytes(Username);
|
||||
byteArray.AddRange(BitConverter.GetBytes(usernameBytes.Length));
|
||||
byteArray.AddRange(usernameBytes);
|
||||
m.Write(Username);
|
||||
|
||||
// Write ModVersion
|
||||
byte[] modVersionBytes = Encoding.UTF8.GetBytes(ModVersion);
|
||||
byteArray.AddRange(BitConverter.GetBytes(modVersionBytes.Length));
|
||||
byteArray.AddRange(modVersionBytes);
|
||||
m.Write(ModVersion);
|
||||
|
||||
byteArray.AddString(InternalEndPoint.ToString());
|
||||
m.Write(InternalEndPoint.ToString());
|
||||
|
||||
// Write AesKeyCrypted
|
||||
byteArray.AddArray(AesKeyCrypted);
|
||||
m.WriteByteArray(AesKeyCrypted);
|
||||
|
||||
// Write AesIVCrypted
|
||||
byteArray.AddArray(AesIVCrypted);
|
||||
m.WriteByteArray(AesIVCrypted);
|
||||
|
||||
|
||||
// Write PassHash
|
||||
byteArray.AddArray(PasswordEncrypted);
|
||||
m.WriteByteArray(PasswordEncrypted);
|
||||
|
||||
return byteArray.ToArray();
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
|
||||
// Read player netHandle
|
||||
PedID = reader.ReadInt32();
|
||||
PedID = m.ReadInt32();
|
||||
|
||||
// Read Username
|
||||
Username = reader.ReadString();
|
||||
Username = m.ReadString();
|
||||
|
||||
// Read ModVersion
|
||||
ModVersion = reader.ReadString();
|
||||
ModVersion = m.ReadString();
|
||||
|
||||
InternalEndPoint=CoreUtils.StringToEndPoint(reader.ReadString());
|
||||
InternalEndPoint = CoreUtils.StringToEndPoint(m.ReadString());
|
||||
|
||||
AesKeyCrypted=reader.ReadByteArray();
|
||||
AesKeyCrypted = m.ReadByteArray();
|
||||
|
||||
AesIVCrypted=reader.ReadByteArray();
|
||||
AesIVCrypted = m.ReadByteArray();
|
||||
|
||||
|
||||
PasswordEncrypted=reader.ReadByteArray();
|
||||
PasswordEncrypted = m.ReadByteArray();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -101,27 +92,25 @@ namespace RageCoop.Core
|
||||
{
|
||||
public PlayerData[] Players { get; set; }
|
||||
public override PacketType Type => PacketType.HandshakeSuccess;
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
var data = new List<byte>();
|
||||
data.AddInt(Players.Length);
|
||||
m.Write(Players.Length);
|
||||
foreach (var p in Players)
|
||||
{
|
||||
data.AddInt(p.ID);
|
||||
data.AddString(p.Username);
|
||||
m.Write(p.ID);
|
||||
m.Write(p.Username);
|
||||
}
|
||||
return data.ToArray();
|
||||
}
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
var reader = new BitReader(array);
|
||||
Players=new PlayerData[reader.ReadInt32()];
|
||||
|
||||
Players = new PlayerData[m.ReadInt32()];
|
||||
for (int i = 0; i < Players.Length; i++)
|
||||
{
|
||||
Players[i] = new PlayerData()
|
||||
{
|
||||
ID=reader.ReadInt32(),
|
||||
Username=reader.ReadString(),
|
||||
ID = m.ReadInt32(),
|
||||
Username = m.ReadString(),
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -133,36 +122,24 @@ namespace RageCoop.Core
|
||||
|
||||
public string Username { get; set; }
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
// Write NetHandle
|
||||
byteArray.AddRange(BitConverter.GetBytes(PedID));
|
||||
m.Write(PedID);
|
||||
|
||||
// Get Username bytes
|
||||
byte[] usernameBytes = Encoding.UTF8.GetBytes(Username);
|
||||
|
||||
// Write UsernameLength
|
||||
byteArray.AddRange(BitConverter.GetBytes(usernameBytes.Length));
|
||||
|
||||
// Write Username
|
||||
byteArray.AddRange(usernameBytes);
|
||||
|
||||
return byteArray.ToArray();
|
||||
m.Write(Username);
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
// Read player netHandle
|
||||
PedID = reader.ReadInt32();
|
||||
PedID = m.ReadInt32();
|
||||
|
||||
// Read Username
|
||||
Username = reader.ReadString();
|
||||
Username = m.ReadString();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -172,22 +149,18 @@ namespace RageCoop.Core
|
||||
public override PacketType Type => PacketType.PlayerDisconnect;
|
||||
public int PedID { get; set; }
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
m.Write(PedID);
|
||||
|
||||
byteArray.AddRange(BitConverter.GetBytes(PedID));
|
||||
|
||||
return byteArray.ToArray();
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
PedID = reader.ReadInt32();
|
||||
PedID = m.ReadInt32();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@ -203,42 +176,38 @@ namespace RageCoop.Core
|
||||
public float Latency { get; set; }
|
||||
public Vector3 Position { get; set; }
|
||||
public bool IsHost;
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
// Write ID
|
||||
byteArray.AddRange(BitConverter.GetBytes(PedID));
|
||||
m.Write(PedID);
|
||||
|
||||
// Write Username
|
||||
byteArray.AddString(Username);
|
||||
m.Write(Username);
|
||||
|
||||
// Write Latency
|
||||
byteArray.AddFloat(Latency);
|
||||
m.Write(Latency);
|
||||
|
||||
byteArray.AddVector3(Position);
|
||||
m.Write(Position);
|
||||
|
||||
byteArray.AddBool(IsHost);
|
||||
|
||||
return byteArray.ToArray();
|
||||
m.Write(IsHost);
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
|
||||
// Read player ID
|
||||
PedID = reader.ReadInt32();
|
||||
PedID = m.ReadInt32();
|
||||
|
||||
// Read Username
|
||||
Username = reader.ReadString();
|
||||
Username = m.ReadString();
|
||||
|
||||
Latency=reader.ReadSingle();
|
||||
Latency = m.ReadFloat();
|
||||
|
||||
Position=reader.ReadVector3();
|
||||
Position = m.ReadVector3();
|
||||
|
||||
IsHost=reader.ReadBoolean();
|
||||
IsHost = m.ReadBoolean();
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,24 +218,24 @@ namespace RageCoop.Core
|
||||
public byte[] Modulus;
|
||||
public byte[] Exponent;
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
byteArray.AddArray(Modulus);
|
||||
|
||||
byteArray.AddArray(Exponent);
|
||||
|
||||
|
||||
return byteArray.ToArray();
|
||||
m.WriteByteArray(Modulus);
|
||||
|
||||
m.WriteByteArray(Exponent);
|
||||
|
||||
|
||||
|
||||
}
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
var reader=new BitReader(array);
|
||||
Modulus=reader.ReadByteArray();
|
||||
Exponent=reader.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
|
||||
@ -26,57 +23,57 @@ namespace RageCoop.Core
|
||||
|
||||
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
|
||||
// Write id
|
||||
byteArray.AddInt(ID);
|
||||
m.Write(ID);
|
||||
|
||||
// Write ShooterID
|
||||
byteArray.AddInt(ShooterID);
|
||||
m.Write(ShooterID);
|
||||
|
||||
byteArray.AddUint(WeaponHash);
|
||||
m.Write(WeaponHash);
|
||||
|
||||
// Write position
|
||||
byteArray.AddVector3(Position);
|
||||
m.Write(Position);
|
||||
|
||||
|
||||
// Write rotation
|
||||
byteArray.AddVector3(Rotation);
|
||||
m.Write(Rotation);
|
||||
|
||||
// Write velocity
|
||||
byteArray.AddVector3(Velocity);
|
||||
byteArray.Add((byte)Flags);
|
||||
m.Write(Velocity);
|
||||
m.Write((byte)Flags);
|
||||
|
||||
|
||||
return byteArray.ToArray();
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
|
||||
// Read id
|
||||
ID = reader.ReadInt32();
|
||||
ID = m.ReadInt32();
|
||||
|
||||
// Read ShooterID
|
||||
ShooterID= reader.ReadInt32();
|
||||
ShooterID = m.ReadInt32();
|
||||
|
||||
WeaponHash= reader.ReadUInt32();
|
||||
WeaponHash = m.ReadUInt32();
|
||||
|
||||
// Read position
|
||||
Position = reader.ReadVector3();
|
||||
Position = m.ReadVector3();
|
||||
|
||||
// Read rotation
|
||||
Rotation = reader.ReadVector3();
|
||||
Rotation = m.ReadVector3();
|
||||
|
||||
// Read velocity
|
||||
Velocity =reader.ReadVector3();
|
||||
Velocity = m.ReadVector3();
|
||||
|
||||
Flags=(ProjectileDataFlags)reader.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
|
||||
@ -19,44 +16,44 @@ namespace RageCoop.Core
|
||||
public Vector3 StartPosition { get; set; }
|
||||
public Vector3 EndPosition { get; set; }
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
|
||||
// Write OwnerID
|
||||
byteArray.AddRange(BitConverter.GetBytes(OwnerID));
|
||||
m.Write(OwnerID);
|
||||
|
||||
// Write weapon hash
|
||||
byteArray.AddRange(BitConverter.GetBytes(WeaponHash));
|
||||
m.Write(WeaponHash);
|
||||
|
||||
// Write StartPosition
|
||||
byteArray.AddVector3(StartPosition);
|
||||
m.Write(StartPosition);
|
||||
|
||||
// Write EndPosition
|
||||
byteArray.AddVector3(EndPosition);
|
||||
m.Write(EndPosition);
|
||||
|
||||
|
||||
|
||||
return byteArray.ToArray();
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
|
||||
// Read OwnerID
|
||||
OwnerID=reader.ReadInt32();
|
||||
OwnerID = m.ReadInt32();
|
||||
|
||||
// Read WeponHash
|
||||
WeaponHash=reader.ReadUInt32();
|
||||
WeaponHash = m.ReadUInt32();
|
||||
|
||||
// Read StartPosition
|
||||
StartPosition=reader.ReadVector3();
|
||||
StartPosition = m.ReadVector3();
|
||||
|
||||
// Read EndPosition
|
||||
EndPosition=reader.ReadVector3();
|
||||
EndPosition = m.ReadVector3();
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
@ -15,24 +12,24 @@ namespace RageCoop.Core
|
||||
|
||||
public bool Hover { get; set; }
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
byteArray.AddInt(VehicleID);
|
||||
byteArray.AddBool(Hover);
|
||||
|
||||
return byteArray.ToArray();
|
||||
m.Write(VehicleID);
|
||||
m.Write(Hover);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
VehicleID=reader.ReadInt32();
|
||||
Hover=reader.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
|
||||
@ -16,24 +13,19 @@ namespace RageCoop.Core
|
||||
|
||||
public int NewOwnerID { get; set; }
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
byteArray.AddInt(ID);
|
||||
byteArray.AddInt(NewOwnerID);
|
||||
|
||||
return byteArray.ToArray();
|
||||
m.Write(ID);
|
||||
m.Write(NewOwnerID);
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
ID=reader.ReadInt32();
|
||||
NewOwnerID=reader.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
|
||||
@ -14,22 +11,22 @@ namespace RageCoop.Core
|
||||
public override PacketType Type => PacketType.PedKilled;
|
||||
public int VictimID { get; set; }
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
byteArray.AddInt(VictimID);
|
||||
return byteArray.ToArray();
|
||||
|
||||
m.Write(VictimID);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
VictimID=reader.ReadInt32();
|
||||
|
||||
VictimID = m.ReadInt32();
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
@ -1,7 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using GTA.Math;
|
||||
using GTA.Math;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
@ -18,31 +16,31 @@ namespace RageCoop.Core
|
||||
public Vector3 StartPosition { get; set; }
|
||||
public Vector3 EndPosition { get; set; }
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>();
|
||||
|
||||
byteArray.AddInt(OwnerID);
|
||||
byteArray.AddUshort(Bone);
|
||||
byteArray.AddUint(WeaponHash);
|
||||
byteArray.AddVector3(StartPosition);
|
||||
byteArray.AddVector3(EndPosition);
|
||||
|
||||
return byteArray.ToArray();
|
||||
m.Write(OwnerID);
|
||||
m.Write(Bone);
|
||||
m.Write(WeaponHash);
|
||||
m.Write(StartPosition);
|
||||
m.Write(EndPosition);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
OwnerID=reader.ReadInt32();
|
||||
Bone=reader.ReadUInt16();
|
||||
WeaponHash=reader.ReadUInt32();
|
||||
StartPosition=reader.ReadVector3();
|
||||
EndPosition=reader.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
|
||||
{
|
||||
@ -58,200 +55,170 @@ namespace RageCoop.Core
|
||||
public string LicensePlate { get; set; }
|
||||
#endregion
|
||||
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
|
||||
List<byte> byteArray = new List<byte>(100);
|
||||
|
||||
byteArray.AddInt(ID);
|
||||
byteArray.AddInt(OwnerID);
|
||||
byteArray.AddUshort((ushort)Flags);
|
||||
byteArray.AddVector3(Position);
|
||||
byteArray.AddQuaternion(Quaternion);
|
||||
byteArray.AddVector3(Velocity);
|
||||
byteArray.AddVector3(RotationVelocity);
|
||||
byteArray.AddFloat(ThrottlePower);
|
||||
byteArray.AddFloat(BrakePower);
|
||||
byteArray.AddFloat(SteeringAngle);
|
||||
m.Write(ID);
|
||||
m.Write(OwnerID);
|
||||
m.Write((ushort)Flags);
|
||||
m.Write(Position);
|
||||
m.Write(Quaternion);
|
||||
m.Write(Velocity);
|
||||
m.Write(RotationVelocity);
|
||||
m.Write(ThrottlePower);
|
||||
m.Write(BrakePower);
|
||||
m.Write(SteeringAngle);
|
||||
|
||||
if (Flags.HasVehFlag(VehicleDataFlags.IsDeluxoHovering))
|
||||
{
|
||||
byteArray.AddFloat(DeluxoWingRatio);
|
||||
m.Write(DeluxoWingRatio);
|
||||
}
|
||||
|
||||
if (Flags.HasVehFlag(VehicleDataFlags.IsFullSync))
|
||||
{
|
||||
byteArray.AddInt(ModelHash);
|
||||
byteArray.AddFloat(EngineHealth);
|
||||
m.Write(ModelHash);
|
||||
m.Write(EngineHealth);
|
||||
|
||||
// Check
|
||||
if (Flags.HasVehFlag(VehicleDataFlags.IsAircraft))
|
||||
{
|
||||
// Write the vehicle landing gear
|
||||
byteArray.Add(LandingGear);
|
||||
m.Write(LandingGear);
|
||||
}
|
||||
if (Flags.HasVehFlag(VehicleDataFlags.HasRoof))
|
||||
{
|
||||
byteArray.Add(RoofState);
|
||||
m.Write(RoofState);
|
||||
}
|
||||
|
||||
// Write vehicle colors
|
||||
byteArray.Add(Colors[0]);
|
||||
byteArray.Add(Colors[1]);
|
||||
m.Write(Colors[0]);
|
||||
m.Write(Colors[1]);
|
||||
|
||||
// Write vehicle mods
|
||||
// Write the count of mods
|
||||
byteArray.AddRange(BitConverter.GetBytes((short)Mods.Count));
|
||||
m.Write((short)Mods.Count);
|
||||
// Loop the dictionary and add the values
|
||||
foreach (KeyValuePair<int, int> mod in Mods)
|
||||
{
|
||||
// Write the mod value
|
||||
byteArray.AddRange(BitConverter.GetBytes(mod.Key));
|
||||
byteArray.AddRange(BitConverter.GetBytes(mod.Value));
|
||||
m.Write(mod.Key);
|
||||
m.Write(mod.Value);
|
||||
}
|
||||
|
||||
if (!DamageModel.Equals(default(VehicleDamageModel)))
|
||||
{
|
||||
// Write boolean = true
|
||||
byteArray.Add(0x01);
|
||||
m.Write(true);
|
||||
// Write vehicle damage model
|
||||
byteArray.Add(DamageModel.BrokenDoors);
|
||||
byteArray.Add(DamageModel.OpenedDoors);
|
||||
byteArray.Add(DamageModel.BrokenWindows);
|
||||
byteArray.AddRange(BitConverter.GetBytes(DamageModel.BurstedTires));
|
||||
byteArray.Add(DamageModel.LeftHeadLightBroken);
|
||||
byteArray.Add(DamageModel.RightHeadLightBroken);
|
||||
m.Write(DamageModel.BrokenDoors);
|
||||
m.Write(DamageModel.OpenedDoors);
|
||||
m.Write(DamageModel.BrokenWindows);
|
||||
m.Write(DamageModel.BurstedTires);
|
||||
m.Write(DamageModel.LeftHeadLightBroken);
|
||||
m.Write(DamageModel.RightHeadLightBroken);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write boolean = false
|
||||
byteArray.Add(0x00);
|
||||
m.Write(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Write LockStatus
|
||||
byteArray.Add((byte)LockStatus);
|
||||
m.Write((byte)LockStatus);
|
||||
|
||||
// Write RadioStation
|
||||
byteArray.Add(RadioStation);
|
||||
m.Write(RadioStation);
|
||||
|
||||
// Write LicensePlate
|
||||
while (LicensePlate.Length<8)
|
||||
{
|
||||
LicensePlate+=" ";
|
||||
}
|
||||
if (LicensePlate.Length>8)
|
||||
{
|
||||
LicensePlate=new string(LicensePlate.Take(8).ToArray());
|
||||
}
|
||||
byteArray.AddRange(Encoding.ASCII.GetBytes(LicensePlate));
|
||||
m.Write(LicensePlate);
|
||||
|
||||
byteArray.Add((byte)(Livery+1));
|
||||
m.Write((byte)(Livery + 1));
|
||||
}
|
||||
return byteArray.ToArray();
|
||||
}
|
||||
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
#region NetIncomingMessageToPacket
|
||||
BitReader reader = new BitReader(array);
|
||||
|
||||
// Read vehicle id
|
||||
ID = reader.ReadInt32();
|
||||
|
||||
OwnerID = reader.ReadInt32();
|
||||
|
||||
Flags=(VehicleDataFlags)reader.ReadUInt16();
|
||||
|
||||
// Read position
|
||||
Position = reader.ReadVector3();
|
||||
|
||||
// Read quaternion
|
||||
Quaternion=reader.ReadQuaternion();
|
||||
|
||||
// Read velocity
|
||||
Velocity =reader.ReadVector3();
|
||||
|
||||
// Read rotation velocity
|
||||
RotationVelocity=reader.ReadVector3();
|
||||
|
||||
// Read throttle power
|
||||
ThrottlePower=reader.ReadSingle();
|
||||
|
||||
// Read brake power
|
||||
BrakePower=reader.ReadSingle();
|
||||
|
||||
// Read steering angle
|
||||
SteeringAngle = reader.ReadSingle();
|
||||
ID = m.ReadInt32();
|
||||
OwnerID = m.ReadInt32();
|
||||
Flags = (VehicleDataFlags)m.ReadUInt16();
|
||||
Position = m.ReadVector3();
|
||||
Quaternion = m.ReadQuaternion();
|
||||
Velocity = m.ReadVector3();
|
||||
RotationVelocity = m.ReadVector3();
|
||||
ThrottlePower = m.ReadFloat();
|
||||
BrakePower = m.ReadFloat();
|
||||
SteeringAngle = m.ReadFloat();
|
||||
|
||||
|
||||
if (Flags.HasVehFlag(VehicleDataFlags.IsDeluxoHovering))
|
||||
{
|
||||
DeluxoWingRatio = reader.ReadSingle();
|
||||
DeluxoWingRatio = m.ReadFloat();
|
||||
}
|
||||
|
||||
if (Flags.HasVehFlag(VehicleDataFlags.IsFullSync))
|
||||
{
|
||||
// Read vehicle model hash
|
||||
ModelHash = reader.ReadInt32();
|
||||
ModelHash = m.ReadInt32();
|
||||
|
||||
// Read vehicle engine health
|
||||
EngineHealth = reader.ReadSingle();
|
||||
EngineHealth = m.ReadFloat();
|
||||
|
||||
|
||||
// Check
|
||||
if (Flags.HasVehFlag(VehicleDataFlags.IsAircraft))
|
||||
{
|
||||
// Read vehicle landing gear
|
||||
LandingGear = reader.ReadByte();
|
||||
LandingGear = m.ReadByte();
|
||||
}
|
||||
if (Flags.HasVehFlag(VehicleDataFlags.HasRoof))
|
||||
{
|
||||
RoofState=reader.ReadByte();
|
||||
RoofState = m.ReadByte();
|
||||
}
|
||||
|
||||
// Read vehicle colors
|
||||
byte vehColor1 = reader.ReadByte();
|
||||
byte vehColor2 = reader.ReadByte();
|
||||
byte vehColor1 = m.ReadByte();
|
||||
byte vehColor2 = m.ReadByte();
|
||||
Colors = new byte[] { vehColor1, vehColor2 };
|
||||
|
||||
// Read vehicle mods
|
||||
// Create new Dictionary
|
||||
Mods = new Dictionary<int, int>();
|
||||
// Read count of mods
|
||||
short vehModCount = reader.ReadInt16();
|
||||
short vehModCount = m.ReadInt16();
|
||||
// Loop
|
||||
for (int i = 0; i < vehModCount; i++)
|
||||
{
|
||||
// Read the mod value
|
||||
Mods.Add(reader.ReadInt32(), reader.ReadInt32());
|
||||
Mods.Add(m.ReadInt32(), m.ReadInt32());
|
||||
}
|
||||
|
||||
if (reader.ReadBoolean())
|
||||
if (m.ReadBoolean())
|
||||
{
|
||||
// Read vehicle damage model
|
||||
DamageModel = new VehicleDamageModel()
|
||||
{
|
||||
BrokenDoors = reader.ReadByte(),
|
||||
OpenedDoors=reader.ReadByte(),
|
||||
BrokenWindows = reader.ReadByte(),
|
||||
BurstedTires = reader.ReadInt16(),
|
||||
LeftHeadLightBroken = reader.ReadByte(),
|
||||
RightHeadLightBroken = reader.ReadByte()
|
||||
BrokenDoors = m.ReadByte(),
|
||||
OpenedDoors = m.ReadByte(),
|
||||
BrokenWindows = m.ReadByte(),
|
||||
BurstedTires = m.ReadInt16(),
|
||||
LeftHeadLightBroken = m.ReadByte(),
|
||||
RightHeadLightBroken = m.ReadByte()
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// Read LockStatus
|
||||
LockStatus=(VehicleLockStatus)reader.ReadByte();
|
||||
LockStatus = (VehicleLockStatus)m.ReadByte();
|
||||
|
||||
// Read RadioStation
|
||||
RadioStation=reader.ReadByte();
|
||||
RadioStation = m.ReadByte();
|
||||
|
||||
LicensePlate=Encoding.ASCII.GetString(reader.ReadBytes(8));
|
||||
LicensePlate = m.ReadString();
|
||||
|
||||
Livery=(int)(reader.ReadByte()-1);
|
||||
Livery = m.ReadByte() - 1;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Lidgren.Network;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
@ -10,20 +10,19 @@ namespace RageCoop.Core
|
||||
public byte[] Buffer { get; set; }
|
||||
public int Recorded { get; set; }
|
||||
public override PacketType Type => PacketType.Voice;
|
||||
public override byte[] Serialize()
|
||||
protected override void Serialize(NetOutgoingMessage m)
|
||||
{
|
||||
var data = new List<byte>();
|
||||
data.AddInt(ID);
|
||||
data.AddArray(Buffer);
|
||||
data.AddInt(Recorded);
|
||||
return data.ToArray();
|
||||
m.Write(ID);
|
||||
m.Write(Buffer);
|
||||
m.Write(Recorded);
|
||||
|
||||
}
|
||||
public override void Deserialize(byte[] array)
|
||||
public override void Deserialize(NetIncomingMessage m)
|
||||
{
|
||||
var reader = new BitReader(array);
|
||||
ID = reader.ReadInt32();
|
||||
Buffer = reader.ReadByteArray();
|
||||
Recorded = reader.ReadInt32();
|
||||
|
||||
ID = m.ReadInt32();
|
||||
Buffer = m.ReadByteArray();
|
||||
Recorded = m.ReadInt32();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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,26 +40,21 @@ 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)
|
||||
{
|
||||
throw new ArgumentException($"Hashed value has collision with another name:{name}, hashed value:{hash}");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Hashed.Add(hash, s);
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
namespace RageCoop.Core.Scripting
|
||||
|
@ -1,6 +1,6 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
@ -9,8 +9,8 @@ namespace RageCoop.Core
|
||||
/// </summary>
|
||||
public class Worker : IDisposable
|
||||
{
|
||||
private SemaphoreSlim _semaphoreSlim;
|
||||
private Thread _workerThread;
|
||||
private readonly SemaphoreSlim _semaphoreSlim;
|
||||
private readonly Thread _workerThread;
|
||||
private bool _stopping = false;
|
||||
/// <summary>
|
||||
/// Name of the worker
|
||||
@ -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
|
||||
{
|
||||
@ -28,7 +28,7 @@ namespace RageCoop.Server
|
||||
/// <summary>
|
||||
/// Th client's IP address and port.
|
||||
/// </summary>
|
||||
public IPEndPoint EndPoint { get { return Connection?.RemoteEndPoint; } }
|
||||
public IPEndPoint EndPoint => Connection?.RemoteEndPoint;
|
||||
|
||||
/// <summary>
|
||||
/// Internal(LAN) address of this client, used for NAT hole-punching
|
||||
@ -62,23 +62,25 @@ namespace RageCoop.Server
|
||||
/// <summary>
|
||||
/// Gets or sets whether to enable automatic respawn for this client's main ped.
|
||||
/// </summary>
|
||||
public bool EnableAutoRespawn {
|
||||
get { return _autoRespawn; }
|
||||
set {
|
||||
public bool EnableAutoRespawn
|
||||
{
|
||||
get => _autoRespawn;
|
||||
set
|
||||
{
|
||||
BaseScript.SetAutoRespawn(this, value);
|
||||
_autoRespawn = value;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _displayNameTag = true;
|
||||
private Stopwatch _latencyWatch = new Stopwatch();
|
||||
private readonly Stopwatch _latencyWatch = new Stopwatch();
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether to enable automatic respawn for this client's main ped.
|
||||
/// </summary>
|
||||
public bool DisplayNameTag
|
||||
{
|
||||
get { return _displayNameTag; }
|
||||
get => _displayNameTag;
|
||||
set
|
||||
{
|
||||
Server.BaseScript.SetNameTag(this, value);
|
||||
|
@ -1,10 +1,4 @@
|
||||
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
|
||||
{
|
||||
|
@ -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())
|
||||
@ -44,6 +42,7 @@ namespace RageCoop.Server
|
||||
}
|
||||
}
|
||||
private IpInfo IpInfo = null;
|
||||
private bool CanAnnounce = false;
|
||||
private void Announce()
|
||||
{
|
||||
HttpResponseMessage response = null;
|
||||
@ -54,7 +53,10 @@ namespace RageCoop.Server
|
||||
{
|
||||
// TLS only
|
||||
ServicePointManager.Expect100Continue = true;
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls13 | SecurityProtocolType.Tls12;
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13 |
|
||||
SecurityProtocolType.Tls12 |
|
||||
SecurityProtocolType.Tls11 |
|
||||
SecurityProtocolType.Tls;
|
||||
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
|
||||
|
||||
try
|
||||
@ -77,6 +79,19 @@ namespace RageCoop.Server
|
||||
Logger?.Error($"MasterServer: {ex.Message}");
|
||||
}
|
||||
}
|
||||
if (!CanAnnounce)
|
||||
{
|
||||
var existing = JsonConvert.DeserializeObject<List<ServerInfo>>(HttpHelper.DownloadString(Util.GetFinalRedirect(Settings.MasterServer))).Where(x => x.address == IpInfo.Address && x.port == Settings.Port.ToString()).FirstOrDefault();
|
||||
if(existing != null)
|
||||
{
|
||||
Logger.Warning("Server info already present in master server, waiting for 10 seconds...");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
CanAnnounce = true;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
Security.GetPublicKey(out var pModulus, out var pExpoenet);
|
||||
@ -144,7 +159,7 @@ namespace RageCoop.Server
|
||||
Thread.Sleep(10 * 60 * 1000);
|
||||
|
||||
API.SendChatMessage("downloading update...");
|
||||
var downloadURL = $"https://github.com/RAGECOOP/RAGECOOP-V/releases/download/nightly/RageCoop.Server-{GetRID()}.zip";
|
||||
var downloadURL = $"https://github.com/RAGECOOP/RAGECOOP-V/releases/download/nightly/RageCoop.Server-{CoreUtils.GetInvariantRID()}.zip";
|
||||
if (Directory.Exists("Update")) { Directory.Delete("Update", true); }
|
||||
HttpHelper.DownloadFile(downloadURL, "Update.zip", null);
|
||||
Logger?.Info("Installing update");
|
||||
@ -161,23 +176,12 @@ namespace RageCoop.Server
|
||||
Logger?.Error("Update", ex);
|
||||
}
|
||||
}
|
||||
static string GetRID()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
return "win-"+RuntimeInformation.OSArchitecture.ToString().ToLower();
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
return "linux-"+RuntimeInformation.OSArchitecture.ToString().ToLower();
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
private void KickAssholes()
|
||||
{
|
||||
foreach (var c in ClientsByNetHandle.Values.ToArray())
|
||||
{
|
||||
if (c.EntitiesCount > 100 && Settings.KickSpamming)
|
||||
if (c.EntitiesCount > Settings.SpamLimit && Settings.KickSpamming)
|
||||
{
|
||||
c.Kick("Bye bye asshole: spamming");
|
||||
API.SendChatMessage($"Asshole {c.Username} was kicked: Spamming");
|
||||
|
@ -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
|
||||
{
|
||||
@ -43,6 +41,7 @@ namespace RageCoop.Server
|
||||
connection.Deny("Username is already taken!");
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
Security.AddConnection(connection.RemoteEndPoint, packet.AesKeyCrypted, packet.AesIVCrypted);
|
||||
@ -68,6 +67,7 @@ namespace RageCoop.Server
|
||||
connection.Deny("Malformed handshak packet!");
|
||||
return;
|
||||
}
|
||||
|
||||
var handshakeSuccess = MainNetServer.CreateMessage();
|
||||
var currentClients = ClientsByID.Values.ToArray();
|
||||
var players = new Packets.PlayerData[currentClients.Length];
|
||||
@ -79,6 +79,7 @@ namespace RageCoop.Server
|
||||
Username = currentClients[i].Username,
|
||||
};
|
||||
}
|
||||
|
||||
new Packets.HandshakeSuccess()
|
||||
{
|
||||
Players = players
|
||||
@ -146,8 +147,6 @@ namespace RageCoop.Server
|
||||
// Send all blips to this player
|
||||
BaseScript.SendServerBlipsTo(new(Entities.Blips.Values), new() { newClient });
|
||||
|
||||
|
||||
|
||||
// Create P2P connection
|
||||
if (Settings.UseP2P)
|
||||
{
|
||||
@ -181,7 +180,7 @@ namespace RageCoop.Server
|
||||
MainNetServer.SendMessage(outgoingMessage, cons, NetDeliveryMethod.ReliableOrdered, 0);
|
||||
}
|
||||
Entities.CleanUp(localClient);
|
||||
_worker.QueueJob(() => API.Events.InvokePlayerDisconnected(localClient));
|
||||
QueueJob(() => API.Events.InvokePlayerDisconnected(localClient));
|
||||
Logger?.Info($"Player {localClient.Username} disconnected! ID:{localClient.Player.ID}");
|
||||
if (ClientsByNetHandle.ContainsKey(localClient.NetHandle)) { ClientsByNetHandle.Remove(localClient.NetHandle); }
|
||||
if (ClientsByName.ContainsKey(localClient.Username.ToLower())) { ClientsByName.Remove(localClient.Username.ToLower()); }
|
||||
|
@ -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
|
||||
@ -14,12 +8,12 @@ namespace RageCoop.Server
|
||||
{
|
||||
private void PedSync(Packets.PedSync packet, Client client)
|
||||
{
|
||||
_worker.QueueJob(() => Entities.Update(packet, client));
|
||||
QueueJob(() => Entities.Update(packet, client));
|
||||
|
||||
bool isPlayer = packet.ID == client.Player.ID;
|
||||
if (isPlayer)
|
||||
{
|
||||
_worker.QueueJob(() => API.Events.InvokePlayerUpdate(client));
|
||||
QueueJob(() => API.Events.InvokePlayerUpdate(client));
|
||||
}
|
||||
|
||||
if (Settings.UseP2P) { return; }
|
||||
@ -49,7 +43,7 @@ namespace RageCoop.Server
|
||||
}
|
||||
private void VehicleSync(Packets.VehicleSync packet, Client client)
|
||||
{
|
||||
_worker.QueueJob(() => Entities.Update(packet, client));
|
||||
QueueJob(() => Entities.Update(packet, client));
|
||||
bool isPlayer = packet.ID == client.Player?.LastVehicle?.ID;
|
||||
|
||||
|
||||
@ -64,7 +58,6 @@ namespace RageCoop.Server
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
else if ((Settings.NpcStreamingDistance != -1) && (packet.Position.DistanceTo(c.Player.Position) > Settings.NpcStreamingDistance))
|
||||
{
|
||||
@ -72,12 +65,11 @@ namespace RageCoop.Server
|
||||
}
|
||||
NetOutgoingMessage outgoingMessage = MainNetServer.CreateMessage();
|
||||
packet.Pack(outgoingMessage);
|
||||
MainNetServer.SendMessage(outgoingMessage, c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.PedSync);
|
||||
MainNetServer.SendMessage(outgoingMessage, c.Connection, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.VehicleSync);
|
||||
}
|
||||
}
|
||||
private void ProjectileSync(Packets.ProjectileSync packet, Client client)
|
||||
{
|
||||
|
||||
if (Settings.UseP2P) { return; }
|
||||
Forward(packet, client, ConnectionChannel.ProjectileSync);
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
@ -56,9 +51,7 @@ namespace RageCoop.Server
|
||||
{
|
||||
try
|
||||
{
|
||||
int len = message.ReadInt32();
|
||||
byte[] data = message.ReadBytes(len);
|
||||
GetHandshake(message.SenderConnection, data.GetPacket<Packets.Handshake>());
|
||||
GetHandshake(message.SenderConnection, message.GetPacket<Packets.Handshake>());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -86,7 +79,7 @@ namespace RageCoop.Server
|
||||
else if (status == NetConnectionStatus.Connected)
|
||||
{
|
||||
PlayerConnected(sender);
|
||||
_worker.QueueJob(() => API.Events.InvokePlayerConnected(sender));
|
||||
QueueJob(() => API.Events.InvokePlayerConnected(sender));
|
||||
Resources.SendTo(sender);
|
||||
}
|
||||
break;
|
||||
@ -106,7 +99,7 @@ namespace RageCoop.Server
|
||||
int id = message.ReadInt32();
|
||||
if (PendingResponses.TryGetValue(id, out var callback))
|
||||
{
|
||||
callback((PacketType)message.ReadByte(), message.ReadBytes(message.ReadInt32()));
|
||||
callback((PacketType)message.ReadByte(), message);
|
||||
PendingResponses.Remove(id);
|
||||
}
|
||||
break;
|
||||
@ -114,19 +107,23 @@ namespace RageCoop.Server
|
||||
case PacketType.Request:
|
||||
{
|
||||
int id = message.ReadInt32();
|
||||
if (RequestHandlers.TryGetValue((PacketType)message.ReadByte(), out var handler))
|
||||
var reqType = (PacketType)message.ReadByte();
|
||||
if (RequestHandlers.TryGetValue(reqType, out var handler))
|
||||
{
|
||||
var response = MainNetServer.CreateMessage();
|
||||
response.Write((byte)PacketType.Response);
|
||||
response.Write(id);
|
||||
handler(message.ReadBytes(message.ReadInt32()), sender).Pack(response);
|
||||
handler(message, sender).Pack(response);
|
||||
MainNetServer.SendMessage(response, message.SenderConnection, NetDeliveryMethod.ReliableOrdered);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Warning("Did not find a request handler of type: " + reqType);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
byte[] data = message.ReadBytes(message.ReadInt32());
|
||||
if (type.IsSyncEvent())
|
||||
{
|
||||
// Sync Events
|
||||
@ -139,8 +136,7 @@ namespace RageCoop.Server
|
||||
{
|
||||
var outgoingMessage = MainNetServer.CreateMessage();
|
||||
outgoingMessage.Write((byte)type);
|
||||
outgoingMessage.Write(data.Length);
|
||||
outgoingMessage.Write(data);
|
||||
outgoingMessage.Write(message.ReadBytes(message.LengthBytes - 1));
|
||||
MainNetServer.SendMessage(outgoingMessage, toSend, NetDeliveryMethod.UnreliableSequenced, (byte)ConnectionChannel.SyncEvents);
|
||||
}
|
||||
}
|
||||
@ -151,7 +147,7 @@ namespace RageCoop.Server
|
||||
}
|
||||
else
|
||||
{
|
||||
HandlePacket(type, data, sender);
|
||||
HandlePacket(type, message, sender);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -191,22 +187,22 @@ namespace RageCoop.Server
|
||||
MainNetServer.Recycle(message);
|
||||
}
|
||||
|
||||
private void HandlePacket(PacketType type, byte[] data, Client sender)
|
||||
private void HandlePacket(PacketType type, NetIncomingMessage msg, Client sender)
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case PacketType.PedSync:
|
||||
PedSync(data.GetPacket<Packets.PedSync>(), sender);
|
||||
PedSync(msg.GetPacket<Packets.PedSync>(), sender);
|
||||
break;
|
||||
|
||||
case PacketType.VehicleSync:
|
||||
VehicleSync(data.GetPacket<Packets.VehicleSync>(), sender);
|
||||
VehicleSync(msg.GetPacket<Packets.VehicleSync>(), sender);
|
||||
break;
|
||||
|
||||
case PacketType.ProjectileSync:
|
||||
ProjectileSync(data.GetPacket<Packets.ProjectileSync>(), sender);
|
||||
ProjectileSync(msg.GetPacket<Packets.ProjectileSync>(), sender);
|
||||
break;
|
||||
|
||||
case PacketType.ChatMessage:
|
||||
@ -215,7 +211,7 @@ namespace RageCoop.Server
|
||||
{
|
||||
return Security.Decrypt(b, sender.EndPoint);
|
||||
});
|
||||
packet.Deserialize(data);
|
||||
packet.Deserialize(msg);
|
||||
ChatMessageReceived(packet.Username, packet.Message, sender);
|
||||
}
|
||||
break;
|
||||
@ -224,7 +220,7 @@ namespace RageCoop.Server
|
||||
{
|
||||
if (Settings.UseVoice && !Settings.UseP2P)
|
||||
{
|
||||
Forward(data.GetPacket<Packets.Voice>(), sender, ConnectionChannel.Voice);
|
||||
Forward(msg.GetPacket<Packets.Voice>(), sender, ConnectionChannel.Voice);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -232,8 +228,8 @@ namespace RageCoop.Server
|
||||
case PacketType.CustomEvent:
|
||||
{
|
||||
Packets.CustomEvent packet = new Packets.CustomEvent();
|
||||
packet.Deserialize(data);
|
||||
_worker.QueueJob(() => API.Events.InvokeCustomEventReceived(packet, sender));
|
||||
packet.Deserialize(msg);
|
||||
QueueJob(() => API.Events.InvokeCustomEventReceived(packet, sender));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -1,23 +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 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;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
using RageCoop.Core.Scripting;
|
||||
|
||||
namespace RageCoop.Server
|
||||
{
|
||||
@ -42,7 +35,7 @@ namespace RageCoop.Server
|
||||
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;
|
||||
@ -54,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,byte[]>> PendingResponses=new();
|
||||
internal Dictionary<PacketType, Func<byte[],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>
|
||||
@ -118,11 +111,22 @@ namespace RageCoop.Server
|
||||
public void Start()
|
||||
{
|
||||
Logger?.Info("================");
|
||||
Logger?.Info($"Server bound to: 0.0.0.0:{Settings.Port}");
|
||||
Logger?.Info($"Listening port: {Settings.Port}");
|
||||
Logger?.Info($"Server version: {Version}");
|
||||
Logger?.Info($"Compatible RAGECOOP versions: {Version.ToString(3)}");
|
||||
Logger?.Info($"Compatible client version: {Version.ToString(3)}");
|
||||
Logger?.Info($"Runtime: {CoreUtils.GetInvariantRID()} => {System.Runtime.InteropServices.RuntimeInformation.RuntimeIdentifier}");
|
||||
Logger?.Info("================");
|
||||
|
||||
Logger?.Info($"Listening addresses:");
|
||||
foreach (NetworkInterface netInterface in NetworkInterface.GetAllNetworkInterfaces())
|
||||
{
|
||||
Logger?.Info($"[{netInterface.Description}]:");
|
||||
IPInterfaceProperties ipProps = netInterface.GetIPProperties();
|
||||
foreach (UnicastIPAddressInformation addr in ipProps.UnicastAddresses)
|
||||
{
|
||||
Logger.Info(string.Join(", ", addr.Address));
|
||||
}
|
||||
Logger.Info("");
|
||||
}
|
||||
if (Settings.UseZeroTier)
|
||||
{
|
||||
Logger?.Info($"Joining ZeroTier network: " + Settings.ZeroTierNetworkID);
|
||||
@ -151,12 +155,12 @@ namespace RageCoop.Server
|
||||
|
||||
MainNetServer = new NetServer(config);
|
||||
MainNetServer.Start();
|
||||
Logger?.Info(string.Format("Server listening on {0}:{1}", config.LocalAddress.ToString(), config.Port));
|
||||
|
||||
BaseScript.API = API;
|
||||
BaseScript.OnStart();
|
||||
Resources.LoadAll();
|
||||
_listenerThread.Start();
|
||||
Logger?.Info("Listening for clients");
|
||||
|
||||
_playerUpdateTimer.Enabled = true;
|
||||
if (Settings.AnnounceSelf)
|
||||
{
|
||||
@ -169,7 +173,6 @@ namespace RageCoop.Server
|
||||
_antiAssholesTimer.Enabled = true;
|
||||
|
||||
|
||||
Logger?.Info("Listening for clients");
|
||||
}
|
||||
/// <summary>
|
||||
/// Terminate threads and stop the server
|
||||
@ -196,12 +199,12 @@ namespace RageCoop.Server
|
||||
{
|
||||
string[] cmdArgs = message.Split(" ");
|
||||
string cmdName = cmdArgs[0].Remove(0, 1);
|
||||
_worker.QueueJob(()=>API.Events.InvokeOnCommandReceived(cmdName, cmdArgs, sender));
|
||||
QueueJob(() => API.Events.InvokeOnCommandReceived(cmdName, cmdArgs, sender));
|
||||
return;
|
||||
}
|
||||
message = message.Replace("~", "");
|
||||
|
||||
_worker.QueueJob(() => API.Events.InvokeOnChatMessage(message, sender));
|
||||
QueueJob(() => API.Events.InvokeOnChatMessage(message, sender));
|
||||
|
||||
foreach (var c in ClientsByNetHandle.Values)
|
||||
{
|
||||
@ -273,12 +276,13 @@ namespace RageCoop.Server
|
||||
{
|
||||
throw new InvalidOperationException("Cannot wait for response from the listener thread!");
|
||||
}
|
||||
|
||||
var received = new AutoResetEvent(false);
|
||||
byte[] response=null;
|
||||
T response = new T();
|
||||
var id = NewRequestID();
|
||||
PendingResponses.Add(id, (type,p) =>
|
||||
PendingResponses.Add(id, (type, m) =>
|
||||
{
|
||||
response=p;
|
||||
response.Deserialize(m);
|
||||
received.Set();
|
||||
});
|
||||
var msg = MainNetServer.CreateMessage();
|
||||
@ -288,15 +292,11 @@ namespace RageCoop.Server
|
||||
MainNetServer.SendMessage(msg, client.Connection, NetDeliveryMethod.ReliableOrdered, (int)channel);
|
||||
if (received.WaitOne(timeout))
|
||||
{
|
||||
var p = new T();
|
||||
p.Deserialize(response);
|
||||
return p;
|
||||
return response;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
internal void SendFile(string path, string name, Client client, Action<float> updateCallback = null)
|
||||
{
|
||||
var fs = File.OpenRead(path);
|
||||
@ -307,11 +307,9 @@ namespace RageCoop.Server
|
||||
internal void SendFile(Stream stream, string name, Client client, int id = default, Action<float> updateCallback = null)
|
||||
{
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
// Logger.Debug("1");
|
||||
id = id == default ? NewFileID() : id;
|
||||
// Logger.Debug("2");
|
||||
var total = stream.Length;
|
||||
// Logger.Debug("3");
|
||||
Logger?.Debug($"Requesting file transfer:{name}, {total}");
|
||||
if (GetResponse<Packets.FileTransferResponse>(client, new Packets.FileTransferRequest()
|
||||
{
|
||||
FileLength = total,
|
||||
@ -320,8 +318,6 @@ namespace RageCoop.Server
|
||||
}, ConnectionChannel.File)?.Response != FileResponse.NeedToDownload)
|
||||
{
|
||||
Logger?.Info($"Skipping file transfer \"{name}\" to {client.Username}");
|
||||
// stream.Close();
|
||||
// stream.Dispose();
|
||||
return;
|
||||
}
|
||||
Logger?.Debug($"Initiating file transfer:{name}, {total}");
|
||||
@ -362,8 +358,6 @@ namespace RageCoop.Server
|
||||
{
|
||||
Logger.Warning($"File trasfer to {client.Username} failed: " + name);
|
||||
}
|
||||
// stream.Close();
|
||||
// stream.Dispose();
|
||||
Logger?.Debug($"All file chunks sent:{name}");
|
||||
InProgressFileTransfers.Remove(id);
|
||||
}
|
||||
|
@ -1,27 +1,24 @@
|
||||
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")
|
||||
{
|
||||
var target = args[1];
|
||||
int i = 0;
|
||||
while (i < 10)
|
||||
while (i++ < 10)
|
||||
{
|
||||
i++;
|
||||
try
|
||||
{
|
||||
Console.WriteLine("Applying update to " + target);
|
||||
@ -99,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.107")]
|
||||
[assembly: AssemblyFileVersion("1.5.3.107")]
|
||||
[assembly: AssemblyVersion("1.5.4.3")]
|
||||
[assembly: AssemblyFileVersion("1.5.4.3")]
|
||||
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]
|
||||
|
||||
|
@ -49,12 +49,12 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Fody" Version="6.6.3">
|
||||
<PackageReference Include="Fody" Version="6.8.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="6.0.8" />
|
||||
<PackageReference Include="SharpZipLib" Version="1.3.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="7.0.9" />
|
||||
<PackageReference Include="SharpZipLib" Version="1.4.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -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
|
||||
{
|
||||
@ -118,8 +117,7 @@ namespace RageCoop.Server.Scripting
|
||||
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))
|
||||
if (CustomEventHandlers.TryGetValue(p.Hash, out List<Action<CustomEventReceivedArgs>> handlers))
|
||||
{
|
||||
handlers.ForEach((x) => { x.Invoke(args); });
|
||||
}
|
||||
@ -173,7 +171,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// <summary>
|
||||
/// All synchronized entities on this server.
|
||||
/// </summary>
|
||||
public ServerEntities Entities { get { return Server.Entities; } }
|
||||
public ServerEntities Entities => Server.Entities;
|
||||
|
||||
#region FUNCTIONS
|
||||
/// <summary>
|
||||
@ -356,10 +354,9 @@ namespace RageCoop.Server.Scripting
|
||||
/// <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)
|
||||
{
|
||||
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>>());
|
||||
}
|
||||
@ -415,7 +412,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// <summary>
|
||||
/// Get a <see cref="Core.Logger"/> that the server is currently using, you should use <see cref="ServerResource.Logger"/> to display resource-specific information.
|
||||
/// </summary>
|
||||
public Logger Logger { get { return Server.Logger; } }
|
||||
public Logger Logger => Server.Logger;
|
||||
|
||||
|
||||
/// <summary>
|
||||
@ -423,8 +420,9 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public Client Host
|
||||
{
|
||||
get { return Server._hostClient; }
|
||||
set {
|
||||
get => Server._hostClient;
|
||||
set
|
||||
{
|
||||
if (Server._hostClient != value)
|
||||
{
|
||||
Server._hostClient?.SendCustomEvent(CustomEvents.IsHost, false);
|
||||
|
@ -1,10 +1,7 @@
|
||||
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
|
||||
{
|
||||
@ -75,15 +72,15 @@ namespace RageCoop.Server.Scripting
|
||||
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
|
||||
|
@ -1,14 +1,9 @@
|
||||
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
|
||||
@ -22,9 +17,8 @@ namespace RageCoop.Server.Scripting
|
||||
Server = server;
|
||||
Logger = server.Logger;
|
||||
}
|
||||
private Dictionary<string,Func<Stream>> ClientResources=new();
|
||||
private Dictionary<string,Func<Stream>> ResourceStreams=new();
|
||||
private List<MemoryStream> MemStreams = new();
|
||||
private readonly Dictionary<string, Stream> ClientResources = new();
|
||||
private readonly Dictionary<string, Stream> ResourceStreams = new();
|
||||
public void LoadAll()
|
||||
{
|
||||
// Packages
|
||||
@ -33,7 +27,7 @@ namespace RageCoop.Server.Scripting
|
||||
Directory.CreateDirectory(path);
|
||||
foreach (var pkg in Directory.GetFiles(path, "*.respkg", SearchOption.AllDirectories))
|
||||
{
|
||||
Logger?.Debug($"Adding resourece from package \"{Path.GetFileNameWithoutExtension(pkg)}\"");
|
||||
Logger?.Debug($"Adding resources from package \"{Path.GetFileNameWithoutExtension(pkg)}\"");
|
||||
var pkgZip = new ZipFile(pkg);
|
||||
foreach (ZipEntry e in pkgZip)
|
||||
{
|
||||
@ -41,15 +35,13 @@ namespace RageCoop.Server.Scripting
|
||||
if (e.Name.StartsWith("Client") && e.Name.EndsWith(".res"))
|
||||
{
|
||||
var stream = pkgZip.GetInputStream(e).ToMemStream();
|
||||
MemStreams.Add(stream);
|
||||
ClientResources.Add(Path.GetFileNameWithoutExtension(e.Name), () => stream);
|
||||
ClientResources.Add(Path.GetFileNameWithoutExtension(e.Name), stream);
|
||||
Logger?.Debug("Resource added: " + Path.GetFileNameWithoutExtension(e.Name));
|
||||
}
|
||||
else if (e.Name.StartsWith("Server") && e.Name.EndsWith(".res"))
|
||||
{
|
||||
var stream = pkgZip.GetInputStream(e).ToMemStream();
|
||||
MemStreams.Add(stream);
|
||||
ResourceStreams.Add(Path.GetFileNameWithoutExtension(e.Name), () => stream);
|
||||
ResourceStreams.Add(Path.GetFileNameWithoutExtension(e.Name), stream);
|
||||
Logger?.Debug("Resource added: " + Path.GetFileNameWithoutExtension(e.Name));
|
||||
}
|
||||
}
|
||||
@ -91,7 +83,7 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
zip.CommitUpdate();
|
||||
zip.Close();
|
||||
ClientResources.Add(Path.GetFileNameWithoutExtension(zipPath), () => File.OpenRead(zipPath));
|
||||
ClientResources.Add(Path.GetFileNameWithoutExtension(zipPath), File.OpenRead(zipPath));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -105,7 +97,7 @@ namespace RageCoop.Server.Scripting
|
||||
{
|
||||
foreach (var file in packed)
|
||||
{
|
||||
ClientResources.Add(Path.GetFileNameWithoutExtension(file),()=>File.OpenRead(file));
|
||||
ClientResources.Add(Path.GetFileNameWithoutExtension(file), File.OpenRead(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -138,7 +130,7 @@ 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;
|
||||
@ -155,7 +147,7 @@ namespace RageCoop.Server.Scripting
|
||||
continue;
|
||||
}
|
||||
Logger?.Info($"Loading resource: " + name);
|
||||
var r = ServerResource.LoadFrom(res.Value(),name, Path.Combine("Resources", "Temp", "Server"), dataFolder, Logger);
|
||||
var r = ServerResource.LoadFrom(res.Value, name, Path.Combine("Resources", "Temp", "Server"), dataFolder, Logger);
|
||||
LoadedResources.Add(r.Name, r);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -215,7 +207,7 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
LoadedResources.Clear();
|
||||
}
|
||||
foreach(var s in MemStreams)
|
||||
foreach (var s in ResourceStreams.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -224,13 +216,27 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger?.Error("[Resources.CloseMemStream]",ex);
|
||||
Logger?.Error("[Resources.CloseStream]", ex);
|
||||
}
|
||||
}
|
||||
foreach (var s in ClientResources.Values)
|
||||
{
|
||||
try
|
||||
{
|
||||
s.Close();
|
||||
s.Dispose();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger?.Error("[Resources.CloseStream]", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void SendTo(Client client)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
if (ClientResources.Count != 0)
|
||||
@ -239,7 +245,7 @@ namespace RageCoop.Server.Scripting
|
||||
foreach (var rs in ClientResources)
|
||||
{
|
||||
Logger?.Debug(rs.Key);
|
||||
Server.SendFile(rs.Value(),rs.Key+".res", client);
|
||||
Server.SendFile(rs.Value, rs.Key + ".res", client);
|
||||
}
|
||||
|
||||
Logger?.Info($"Resources sent to:{client.Username}");
|
||||
@ -253,6 +259,12 @@ namespace RageCoop.Server.Scripting
|
||||
{
|
||||
Logger?.Warning($"Client {client.Username} failed to load resource.");
|
||||
}
|
||||
}
|
||||
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
|
||||
{
|
||||
@ -33,68 +30,28 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public ServerPed GetPedByID(int id)
|
||||
{
|
||||
if(Peds.TryGetValue(id,out var ped))
|
||||
{
|
||||
return ped;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public ServerPed GetPedByID(int id) => Peds.TryGetValue(id, out var ped) ? ped : null;
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="ServerVehicle"/> by it's id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public ServerVehicle GetVehicleByID(int id)
|
||||
{
|
||||
if (Vehicles.TryGetValue(id, out var veh))
|
||||
{
|
||||
return veh;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public ServerVehicle GetVehicleByID(int id) => Vehicles.TryGetValue(id, out var veh) ? veh : null;
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="ServerProp"/> owned by server from it's ID.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public ServerProp GetPropByID(int id)
|
||||
{
|
||||
if (ServerProps.TryGetValue(id, out var obj))
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public ServerProp GetPropByID(int id) => ServerProps.TryGetValue(id, out var obj) ? obj : null;
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="ServerBlip"/> by it's id.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public ServerBlip GetBlipByID(int id)
|
||||
{
|
||||
if (Blips.TryGetValue(id, out var obj))
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public ServerBlip GetBlipByID(int id) => Blips.TryGetValue(id, out var obj) ? obj : null;
|
||||
|
||||
/// <summary>
|
||||
/// Create a static prop owned by server.
|
||||
@ -164,45 +121,32 @@ namespace RageCoop.Server.Scripting
|
||||
/// Get all peds on this server
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ServerPed[] GetAllPeds()
|
||||
{
|
||||
return Peds.Values.ToArray();
|
||||
}
|
||||
public ServerPed[] GetAllPeds() => Peds.Values.ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Get all vehicles on this server
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ServerVehicle[] GetAllVehicles()
|
||||
{
|
||||
return Vehicles.Values.ToArray();
|
||||
}
|
||||
public ServerVehicle[] GetAllVehicles() => Vehicles.Values.ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Get all static prop objects owned by server
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ServerProp[] GetAllProps()
|
||||
{
|
||||
return ServerProps.Values.ToArray();
|
||||
}
|
||||
public ServerProp[] GetAllProps() => ServerProps.Values.ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Get all blips owned by server
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ServerBlip[] GetAllBlips()
|
||||
{
|
||||
return Blips.Values.ToArray();
|
||||
}
|
||||
public ServerBlip[] GetAllBlips() => Blips.Values.ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Not thread safe
|
||||
/// </summary>
|
||||
internal void Update(Packets.PedSync p, Client sender)
|
||||
{
|
||||
ServerPed ped;
|
||||
if(!Peds.TryGetValue(p.ID,out ped))
|
||||
if (!Peds.TryGetValue(p.ID, out ServerPed ped))
|
||||
{
|
||||
Peds.TryAdd(p.ID, ped = new ServerPed(Server));
|
||||
ped.ID = p.ID;
|
||||
@ -229,8 +173,7 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
internal void Update(Packets.VehicleSync p, Client sender)
|
||||
{
|
||||
ServerVehicle veh;
|
||||
if (!Vehicles.TryGetValue(p.ID, out veh))
|
||||
if (!Vehicles.TryGetValue(p.ID, out ServerVehicle veh))
|
||||
{
|
||||
Vehicles.TryAdd(p.ID, veh = new ServerVehicle(Server));
|
||||
veh.ID = p.ID;
|
||||
@ -277,14 +220,8 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
}
|
||||
|
||||
internal void RemoveProp(int id)
|
||||
{
|
||||
ServerProps.TryRemove(id, out _);
|
||||
}
|
||||
internal void RemoveServerBlip(int id)
|
||||
{
|
||||
Blips.TryRemove(id, out _);
|
||||
}
|
||||
internal void RemoveProp(int id) => ServerProps.TryRemove(id, out _);
|
||||
internal void RemoveServerBlip(int id) => Blips.TryRemove(id, out _);
|
||||
internal void RemovePed(int id)
|
||||
{
|
||||
Peds.TryRemove(id, out var ped);
|
||||
@ -299,12 +236,11 @@ namespace RageCoop.Server.Scripting
|
||||
if (Peds.ContainsKey(ped.ID))
|
||||
{
|
||||
Peds[ped.ID] = ped;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Peds.TryAdd(ped.ID, ped);
|
||||
}
|
||||
}
|
||||
internal int RequestNetworkID()
|
||||
{
|
||||
int ID = 0;
|
||||
|
@ -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
|
||||
{
|
||||
@ -70,7 +67,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public virtual Vector3 Position
|
||||
{
|
||||
get { return _pos; }
|
||||
get => _pos;
|
||||
set { _pos = value; Owner.SendNativeCall(Hash.SET_ENTITY_COORDS_NO_OFFSET, Handle, value.X, value.Y, value.Z, 1, 1, 1); }
|
||||
}
|
||||
internal Vector3 _pos;
|
||||
@ -80,7 +77,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public virtual Vector3 Rotation
|
||||
{
|
||||
get { return _rot; }
|
||||
get => _rot;
|
||||
set { _rot = value; Owner.SendNativeCall(Hash.SET_ENTITY_ROTATION, Handle, value.X, value.Y, value.Z, 2, 1); }
|
||||
}
|
||||
internal Vector3 _rot;
|
||||
@ -137,7 +134,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public override Vector3 Position
|
||||
{
|
||||
get { return _pos; }
|
||||
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); }
|
||||
}
|
||||
|
||||
@ -146,7 +143,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public override Vector3 Rotation
|
||||
{
|
||||
get { return _rot; }
|
||||
get => _rot;
|
||||
set { _rot = value; Server.API.SendNativeCall(null, Hash.SET_ENTITY_ROTATION, Handle, value.X, value.Y, value.Z, 2, 1); }
|
||||
}
|
||||
|
||||
@ -198,7 +195,8 @@ 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);
|
||||
}
|
||||
@ -215,7 +213,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public override Vector3 Rotation
|
||||
{
|
||||
get { return _quat.ToEulerAngles().ToDegree(); }
|
||||
get => _quat.ToEulerAngles().ToDegree();
|
||||
set { Owner.SendNativeCall(Hash.SET_ENTITY_ROTATION, Handle, value.X, value.Y, value.Z); }
|
||||
}
|
||||
|
||||
@ -225,7 +223,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public Quaternion Quaternion
|
||||
{
|
||||
get { return _quat; }
|
||||
get => _quat;
|
||||
set { _quat = value; Owner.SendNativeCall(Hash.SET_ENTITY_QUATERNION, Handle, value.X, value.Y, value.Z, value.W); }
|
||||
}
|
||||
}
|
||||
@ -263,8 +261,9 @@ namespace RageCoop.Server.Scripting
|
||||
/// <summary>
|
||||
/// Color of this blip
|
||||
/// </summary>
|
||||
public BlipColor Color {
|
||||
get { return _color; }
|
||||
public BlipColor Color
|
||||
{
|
||||
get => _color;
|
||||
set { _color = value; Update(); }
|
||||
}
|
||||
|
||||
@ -272,8 +271,9 @@ namespace RageCoop.Server.Scripting
|
||||
/// <summary>
|
||||
/// Sprite of this blip
|
||||
/// </summary>
|
||||
public BlipSprite Sprite {
|
||||
get { return _sprite; }
|
||||
public BlipSprite Sprite
|
||||
{
|
||||
get => _sprite;
|
||||
set { _sprite = value; Update(); }
|
||||
}
|
||||
|
||||
@ -283,7 +283,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public float Scale
|
||||
{
|
||||
get { return _scale; }
|
||||
get => _scale;
|
||||
set { _scale = value; Update(); }
|
||||
}
|
||||
|
||||
@ -293,7 +293,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public Vector3 Position
|
||||
{
|
||||
get { return _pos; }
|
||||
get => _pos;
|
||||
set { _pos = value; Update(); }
|
||||
}
|
||||
|
||||
@ -303,7 +303,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public int Rotation
|
||||
{
|
||||
get { return _rot; }
|
||||
get => _rot;
|
||||
set { _rot = value; Update(); }
|
||||
}
|
||||
|
||||
@ -313,7 +313,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public string Name
|
||||
{
|
||||
get { return _name;}
|
||||
get => _name;
|
||||
set { _name = value; Update(); }
|
||||
}
|
||||
|
||||
@ -372,7 +372,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public BlipColor Color
|
||||
{
|
||||
get { return _color; }
|
||||
get => _color;
|
||||
set { _color = value; Update(); }
|
||||
}
|
||||
|
||||
@ -382,7 +382,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public BlipSprite Sprite
|
||||
{
|
||||
get { return _sprite; }
|
||||
get => _sprite;
|
||||
set { _sprite = value; Update(); }
|
||||
}
|
||||
|
||||
@ -392,7 +392,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// </summary>
|
||||
public float Scale
|
||||
{
|
||||
get { return _scale; }
|
||||
get => _scale;
|
||||
set { _scale = value; Update(); }
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,13 @@
|
||||
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
|
||||
{
|
||||
@ -17,8 +18,22 @@ namespace RageCoop.Server.Scripting
|
||||
{
|
||||
|
||||
internal ServerResource(PluginConfig config) : base(config) { }
|
||||
internal static ServerResource LoadFrom(string resDir, string dataFolder, Logger logger = null, bool isTemp = false)
|
||||
internal static ServerResource LoadFrom(string resDir, string dataFolder, Logger logger = null)
|
||||
{
|
||||
var runtimeLibs = Path.Combine(resDir, "RuntimeLibs", CoreUtils.GetInvariantRID());
|
||||
if (Directory.Exists(runtimeLibs))
|
||||
{
|
||||
logger?.Debug("Applying runtime libraries from " + CoreUtils.GetInvariantRID());
|
||||
CoreUtils.CopyFilesRecursively(new(runtimeLibs), new(resDir));
|
||||
}
|
||||
|
||||
runtimeLibs = Path.Combine(resDir, "RuntimeLibs", RuntimeInformation.RuntimeIdentifier);
|
||||
if (Directory.Exists(runtimeLibs))
|
||||
{
|
||||
logger?.Debug("Applying runtime libraries from " + CoreUtils.GetInvariantRID());
|
||||
CoreUtils.CopyFilesRecursively(new(runtimeLibs), new(resDir));
|
||||
}
|
||||
|
||||
var conf = new PluginConfig(Path.GetFullPath(Path.Combine(resDir, Path.GetFileName(resDir) + ".dll")))
|
||||
{
|
||||
PreferSharedTypes = true,
|
||||
@ -66,6 +81,9 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
foreach (var a in assemblies)
|
||||
{
|
||||
if (a.Key.Name.ToLower() == r.Name.ToLower() + ".dll")
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
r.LoadScriptsFromAssembly(a.Key, a.Value);
|
||||
@ -79,13 +97,16 @@ namespace RageCoop.Server.Scripting
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
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); }
|
||||
Directory.CreateDirectory(tmpDir);
|
||||
new FastZip().ExtractZip(input, tmpDir, FastZip.Overwrite.Always, null, null, null, true, true);
|
||||
return LoadFrom(tmpDir, dataFolder, logger, true);
|
||||
return LoadFrom(tmpDir, dataFolder, logger);
|
||||
}
|
||||
/// <summary>
|
||||
/// Name of the resource
|
||||
|
@ -1,5 +1,5 @@
|
||||
using System;
|
||||
using RageCoop.Core.Scripting;
|
||||
using RageCoop.Core.Scripting;
|
||||
using System;
|
||||
|
||||
namespace RageCoop.Server.Scripting
|
||||
{
|
||||
@ -35,7 +35,7 @@ namespace RageCoop.Server.Scripting
|
||||
/// <summary>
|
||||
/// Eqivalent of <see cref="ServerResource.Logger"/> in <see cref="CurrentResource"/>
|
||||
/// </summary>
|
||||
public Core.Logger Logger { get { return CurrentResource.Logger; } }
|
||||
public Core.Logger Logger => CurrentResource.Logger;
|
||||
}
|
||||
/// <summary>
|
||||
/// Decorate your method with this attribute and use <see cref="API.RegisterCommands{T}"/> or <see cref="API.RegisterCommands(object)"/> to register commands.
|
||||
|
@ -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
|
||||
{
|
||||
@ -18,7 +13,7 @@ namespace RageCoop.Server
|
||||
Logger = logger;
|
||||
}
|
||||
public RSA RSA = RSA.Create(2048);
|
||||
private Dictionary<IPEndPoint, Aes> SecuredConnections = new Dictionary<IPEndPoint, Aes>();
|
||||
private readonly Dictionary<IPEndPoint, Aes> SecuredConnections = new Dictionary<IPEndPoint, Aes>();
|
||||
|
||||
public bool HasSecuredConnection(IPEndPoint target)
|
||||
{
|
||||
|
@ -28,7 +28,7 @@
|
||||
/// <summary>
|
||||
/// The website address to be shown on master server
|
||||
/// </summary>
|
||||
public string Website { get; set; } = "https://ragecoop.online/";
|
||||
public string Website { get; set; } = "https://ragecoop.com/";
|
||||
|
||||
/// <summary>
|
||||
/// The description to be shown on master server
|
||||
@ -58,7 +58,7 @@
|
||||
/// <summary>
|
||||
/// Master server address, mostly doesn't need to be changed.
|
||||
/// </summary>
|
||||
public string MasterServer { get; set; } = "https://masterserver.ragecoop.online/";
|
||||
public string MasterServer { get; set; } = "https://masterserver.ragecoop.com/";
|
||||
|
||||
/// <summary>
|
||||
/// See <see cref="Core.Logger.LogLevel"/>.
|
||||
@ -119,5 +119,10 @@
|
||||
/// Kick spamming assholes
|
||||
/// </summary>
|
||||
public bool KickSpamming { get; set; } = true;
|
||||
|
||||
/// <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;
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,15 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using System.Xml.Serialization;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
global using System.Collections.Generic;
|
||||
using Lidgren.Network;
|
||||
using System;
|
||||
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,22 +34,6 @@ namespace RageCoop.Server
|
||||
return "";
|
||||
}
|
||||
}
|
||||
public static (byte, byte[]) GetBytesFromObject(object obj)
|
||||
{
|
||||
return obj switch
|
||||
{
|
||||
byte _ => (0x01, BitConverter.GetBytes((byte)obj)),
|
||||
short _ => (0x02, BitConverter.GetBytes((short)obj)),
|
||||
ushort _ => (0x03, BitConverter.GetBytes((ushort)obj)),
|
||||
int _ => (0x04, BitConverter.GetBytes((int)obj)),
|
||||
uint _ => (0x05, BitConverter.GetBytes((uint)obj)),
|
||||
long _ => (0x06, BitConverter.GetBytes((long)obj)),
|
||||
ulong _ => (0x07, BitConverter.GetBytes((ulong)obj)),
|
||||
float _ => (0x08, BitConverter.GetBytes((float)obj)),
|
||||
bool _ => (0x09, BitConverter.GetBytes((bool)obj)),
|
||||
_ => (0x0, null),
|
||||
};
|
||||
}
|
||||
public static List<NetConnection> Exclude(this IEnumerable<NetConnection> connections, NetConnection toExclude)
|
||||
{
|
||||
return new(connections.Where(e => e != toExclude));
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user