Compare commits
22 Commits
Author | SHA1 | Date | |
---|---|---|---|
3b901d8e6c | |||
9764484f4a | |||
5f781f6f48 | |||
fcd7e18d9b | |||
564d1467f6 | |||
8bd6ea15a3 | |||
3c7f16f7a4 | |||
393a401860 | |||
39b780e518 | |||
4a54851c51 | |||
f0eefa575c | |||
3fc813b2d8 | |||
fbff72ff14 | |||
4e52407591 | |||
4e6fde129d | |||
92e1a970a8 | |||
d0eb0b7818 | |||
14151d7b2c | |||
1f8d70a520 | |||
2cb5baf5f7 | |||
34e33937e2 | |||
9287aba0f9 |
32
.github/workflows/docker-build.yaml
vendored
Normal file
32
.github/workflows/docker-build.yaml
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
name: Build and Push Docker Image to GHCR
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set repo owner to lowercase
|
||||
run: echo "REPO_OWNER=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_ENV
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push Docker image to GHCR
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: ghcr.io/${{ env.REPO_OWNER }}/ragecoop-v:latest
|
||||
dockerfile: Dockerfile
|
65
.github/workflows/nightly-build.yaml
vendored
65
.github/workflows/nightly-build.yaml
vendored
@ -1,13 +1,11 @@
|
||||
name: Nightly-build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "dev-nightly" ]
|
||||
on: push
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: windows-latest
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
dotnet-version: ['6.0.x']
|
||||
@ -21,15 +19,16 @@ jobs:
|
||||
- name: Restore dependencies
|
||||
run: dotnet restore
|
||||
- name: Restore nuget packages
|
||||
run: nuget restore
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y nuget
|
||||
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 publish RageCoop.Server/RageCoop.Server.csproj --self-contained -p:PublishSingleFile=true -p:PublishTrimmed=false -r win-x64 -o bin/Release/Server/win-x64 -c Release
|
||||
- name: Build server linux-x64
|
||||
run: dotnet publish RageCoop.Server/RageCoop.Server.csproj --self-contained -p:PublishSingleFile=true -p:PublishTrimmed=false -r linux-x64 -o bin/Release/Server/linux-x64 -c Release
|
||||
- name: Build server linux-arm
|
||||
run: dotnet publish RageCoop.Server/RageCoop.Server.csproj --self-contained -p:PublishSingleFile=true -p:PublishTrimmed=false -r linux-arm -o bin/Release/Server/linux-arm -c Release
|
||||
- uses: vimtor/action-zip@v1
|
||||
with:
|
||||
files: bin/Release/Client
|
||||
@ -44,55 +43,3 @@ jobs:
|
||||
with:
|
||||
files: bin/Release/Server/linux-x64
|
||||
dest: RageCoop.Server-linux-x64.zip
|
||||
|
||||
- uses: vimtor/action-zip@v1
|
||||
with:
|
||||
files: bin/Release/Server/linux-arm
|
||||
dest: RageCoop.Server-linux-arm.zip
|
||||
|
||||
- uses: WebFreak001/deploy-nightly@v1.1.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # automatically provided by github actions
|
||||
with:
|
||||
upload_url: https://uploads.github.com/repos/RAGECOOP/RAGECOOP-V/releases/70603992/assets{?name,label}
|
||||
release_id: 70603992
|
||||
asset_path: RageCoop.Client.zip
|
||||
asset_name: RageCoop.Client.zip
|
||||
asset_content_type: application/zip
|
||||
max_releases: 7
|
||||
|
||||
- uses: WebFreak001/deploy-nightly@v1.1.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # automatically provided by github actions
|
||||
with:
|
||||
upload_url: https://uploads.github.com/repos/RAGECOOP/RAGECOOP-V/releases/70603992/assets{?name,label}
|
||||
release_id: 70603992
|
||||
asset_path: RageCoop.Server-win-x64.zip
|
||||
asset_name: RageCoop.Server-win-x64.zip
|
||||
asset_content_type: application/zip
|
||||
max_releases: 7
|
||||
|
||||
- uses: WebFreak001/deploy-nightly@v1.1.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # automatically provided by github actions
|
||||
with:
|
||||
upload_url: https://uploads.github.com/repos/RAGECOOP/RAGECOOP-V/releases/70603992/assets{?name,label}
|
||||
release_id: 70603992
|
||||
asset_path: RageCoop.Server-linux-x64.zip
|
||||
asset_name: RageCoop.Server-linux-x64.zip
|
||||
asset_content_type: application/zip
|
||||
max_releases: 7
|
||||
|
||||
|
||||
- uses: WebFreak001/deploy-nightly@v1.1.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # automatically provided by github actions
|
||||
with:
|
||||
upload_url: https://uploads.github.com/repos/RAGECOOP/RAGECOOP-V/releases/70603992/assets{?name,label}
|
||||
release_id: 70603992
|
||||
asset_path: RageCoop.Server-linux-arm.zip
|
||||
asset_name: RageCoop.Server-linux-arm.zip
|
||||
asset_content_type: application/zip
|
||||
max_releases: 7
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@
|
||||
**/packages
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/.idea
|
28
Dockerfile
Normal file
28
Dockerfile
Normal file
@ -0,0 +1,28 @@
|
||||
# Use the official image as a parent image
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
|
||||
WORKDIR /app
|
||||
EXPOSE 80
|
||||
|
||||
# Use the SDK image to build the app
|
||||
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
|
||||
WORKDIR /src
|
||||
|
||||
# Copy csproj and restore as distinct layers
|
||||
COPY RageCoop.Server/*.csproj ./RageCoop.Server/
|
||||
COPY libs/*.dll ./libs/
|
||||
|
||||
# Assuming RageCoop.Core is a dependency, if not, you can comment out the next line
|
||||
COPY RageCoop.Core/*.csproj ./RageCoop.Core/
|
||||
|
||||
RUN dotnet restore RageCoop.Server/RageCoop.Server.csproj
|
||||
|
||||
# Copy everything else and build
|
||||
COPY . .
|
||||
WORKDIR /src/RageCoop.Server
|
||||
RUN dotnet publish -c Release -o /app
|
||||
|
||||
# Build runtime image
|
||||
FROM base AS final
|
||||
WORKDIR /app
|
||||
COPY --from=build-env /app .
|
||||
ENTRYPOINT ["dotnet", "RageCoop.Server.dll"]
|
@ -15,7 +15,7 @@ RAGECOOP brings multiplayer experience to the story mode, you can complete missi
|
||||
|
||||
# 👁 Requirements
|
||||
- ScriptHookV
|
||||
- ScriptHookVDotNet 3.5.1 or later
|
||||
- ScriptHookVDotNet 3.6.0 or later
|
||||
- .NET Framework 4.8 Runtime or SDK
|
||||
|
||||
# 📋 Building the project
|
||||
@ -49,7 +49,7 @@ Then run `dotnet build` in the solution directory, built binaries are in the `bi
|
||||
5. Decent compatibility with other mods, set up a private modded server to have some fun!
|
||||
6. Weaponized vehicle sync(WIP).
|
||||
7. Optimization for high-Ping condition, play with friends around the world!
|
||||
8. Powerful scripting API and resource system, easily [add multiplayer functionality to your mod](HTTPS://docs.ragecoop.online).
|
||||
8. Powerful scripting API and resource system, easily [add multiplayer functionality to your mod](HTTPS://docs.ragecoop.com).
|
||||
|
||||
# ⚠ Known issues
|
||||
|
||||
|
@ -170,7 +170,7 @@ namespace RageCoop.Client
|
||||
P.Health = 1;
|
||||
Game.Player.WantedLevel = 0;
|
||||
Main.Logger.Debug("Player died.");
|
||||
Scripting.API.Events.InvokePlayerDied();
|
||||
Scripting.API.Events.InvokePlayerDied(KillMessage());
|
||||
}
|
||||
GTA.UI.Screen.StopEffects();
|
||||
}
|
||||
@ -181,7 +181,7 @@ namespace RageCoop.Client
|
||||
}
|
||||
else if (P.IsDead && !_lastDead)
|
||||
{
|
||||
Scripting.API.Events.InvokePlayerDied();
|
||||
Scripting.API.Events.InvokePlayerDied(KillMessage());
|
||||
}
|
||||
|
||||
_lastDead = P.IsDead;
|
||||
@ -326,7 +326,8 @@ namespace RageCoop.Client
|
||||
WorldThread.Traffic(true);
|
||||
Function.Call(Hash.SET_ENABLE_VEHICLE_SLIPSTREAMING, false);
|
||||
CoopMenu.DisconnectedMenuSetting();
|
||||
GTA.UI.Notification.Show("~r~Disconnected: " + reason);
|
||||
if (reason != "Abort")
|
||||
GTA.UI.Notification.Show("~r~Disconnected: " + reason);
|
||||
LocalPlayerID = default;
|
||||
});
|
||||
Memory.RestorePatches();
|
||||
@ -393,5 +394,15 @@ namespace RageCoop.Client
|
||||
});
|
||||
}
|
||||
|
||||
private string KillMessage()
|
||||
{
|
||||
if (P.Killer != null)
|
||||
{
|
||||
var killer = EntityPool.GetPedByHandle(P.Killer.Handle);
|
||||
if (killer != null && killer.ID == killer.Owner.ID)
|
||||
return $"~h~{PlayerList.GetPlayer(LocalPlayerID).Username}~h~ was killed by ~h~{killer.Owner.Username}~h~ ({P.CauseOfDeath})";
|
||||
}
|
||||
return $"~h~{PlayerList.GetPlayer(LocalPlayerID).Username}~h~ died";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ namespace RageCoop.Client.Menus
|
||||
{
|
||||
|
||||
Menu.Banner.Color = Color.FromArgb(225, 0, 0, 0);
|
||||
Menu.Title.Color = Color.FromArgb(255, 165, 0);
|
||||
Menu.BannerText.Color = Color.FromArgb(255, 165, 0);
|
||||
|
||||
_usernameItem.Activated += UsernameActivated;
|
||||
_passwordItem.Activated += _passwordActivated;
|
||||
|
@ -25,7 +25,7 @@ namespace RageCoop.Client
|
||||
static DebugMenu()
|
||||
{
|
||||
Menu.Banner.Color = Color.FromArgb(225, 0, 0, 0);
|
||||
Menu.Title.Color = Color.FromArgb(255, 165, 0);
|
||||
Menu.BannerText.Color = Color.FromArgb(255, 165, 0);
|
||||
|
||||
|
||||
DiagnosticMenu.Opening += (sender, e) =>
|
||||
|
@ -22,7 +22,7 @@ namespace RageCoop.Client
|
||||
static DevToolMenu()
|
||||
{
|
||||
Menu.Banner.Color = Color.FromArgb(225, 0, 0, 0);
|
||||
Menu.Title.Color = Color.FromArgb(255, 165, 0);
|
||||
Menu.BannerText.Color = Color.FromArgb(255, 165, 0);
|
||||
|
||||
enableItem.Activated += enableItem_Activated;
|
||||
enableItem.Checked = false;
|
||||
|
@ -30,7 +30,7 @@ namespace RageCoop.Client.Menus
|
||||
static ServersMenu()
|
||||
{
|
||||
Menu.Banner.Color = Color.FromArgb(225, 0, 0, 0);
|
||||
Menu.Title.Color = Color.FromArgb(255, 165, 0);
|
||||
Menu.BannerText.Color = Color.FromArgb(255, 165, 0);
|
||||
|
||||
Menu.Opening += (object sender, System.ComponentModel.CancelEventArgs e) =>
|
||||
{
|
||||
@ -76,7 +76,7 @@ namespace RageCoop.Client.Menus
|
||||
foreach (ServerInfo server in serverList)
|
||||
{
|
||||
string address = $"{server.address}:{server.port}";
|
||||
NativeItem tmpItem = new NativeItem($"[{server.country}] {server.name}", $"~b~{address}~s~~n~~g~Version {server.version}.x~s~") { AltTitle = $"[{server.players}/{server.maxPlayers}]" };
|
||||
NativeItem tmpItem = new NativeItem($"[{server.country}] {server.name}", $"~b~{address}~s~~n~~g~Version {server.version}~s~") { AltTitle = $"[{server.players}/{server.maxPlayers}]" };
|
||||
tmpItem.Activated += (object sender, EventArgs e) =>
|
||||
{
|
||||
try
|
||||
|
@ -17,16 +17,19 @@ namespace RageCoop.Client.Menus
|
||||
private static readonly NativeCheckboxItem _disableTrafficItem = new NativeCheckboxItem("Disable Traffic (NPCs/Vehicles)", "Local traffic only", Main.Settings.DisableTraffic);
|
||||
private static readonly NativeCheckboxItem _flipMenuItem = new NativeCheckboxItem("Flip menu", Main.Settings.FlipMenu);
|
||||
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 _showBlip = new NativeCheckboxItem("Show player blip", "Show other player's blip on map", Main.Settings.ShowPlayerBlip);
|
||||
private static readonly NativeCheckboxItem _showNametag = new NativeCheckboxItem("Show player nametag", "Show other player's nametag on your screen", Main.Settings.ShowPlayerNameTag);
|
||||
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 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());
|
||||
private static readonly NativeItem _pedSoftLimit = new NativeItem("Ped limit (soft)", "The game won't spawn more NPCs if the limit is exceeded. \n-1 for unlimited (not recommended).", Main.Settings.WorldPedSoftLimit.ToString());
|
||||
|
||||
static SettingsMenu()
|
||||
{
|
||||
Menu.Banner.Color = Color.FromArgb(225, 0, 0, 0);
|
||||
Menu.Title.Color = Color.FromArgb(255, 165, 0);
|
||||
Menu.BannerText.Color = Color.FromArgb(255, 165, 0);
|
||||
|
||||
_disableTrafficItem.CheckboxChanged += DisableTrafficCheckboxChanged;
|
||||
_disablePauseAlt.CheckboxChanged += DisablePauseAltCheckboxChanged;
|
||||
@ -35,6 +38,17 @@ namespace RageCoop.Client.Menus
|
||||
_menuKey.Activated += ChaneMenuKey;
|
||||
_passengerKey.Activated += ChangePassengerKey;
|
||||
_vehicleSoftLimit.Activated += VehicleSoftLimitActivated;
|
||||
_pedSoftLimit.Activated += PedSoftLimitActivated;
|
||||
_showBlip.Activated += (s, e) =>
|
||||
{
|
||||
Main.Settings.ShowPlayerBlip = _showBlip.Checked;
|
||||
Util.SaveSettings();
|
||||
};
|
||||
_showNametag.Activated += (s, e) =>
|
||||
{
|
||||
Main.Settings.ShowPlayerNameTag = _showNametag.Checked;
|
||||
Util.SaveSettings();
|
||||
};
|
||||
|
||||
Menu.Add(_disableTrafficItem);
|
||||
Menu.Add(_disablePauseAlt);
|
||||
@ -43,6 +57,9 @@ namespace RageCoop.Client.Menus
|
||||
Menu.Add(_menuKey);
|
||||
Menu.Add(_passengerKey);
|
||||
Menu.Add(_vehicleSoftLimit);
|
||||
Menu.Add(_pedSoftLimit);
|
||||
Menu.Add(_showBlip);
|
||||
Menu.Add(_showNametag);
|
||||
}
|
||||
|
||||
private static void DisableVoiceCheckboxChanged(object sender, EventArgs e)
|
||||
@ -75,7 +92,19 @@ namespace RageCoop.Client.Menus
|
||||
Main.Settings.WorldVehicleSoftLimit = int.Parse(
|
||||
Game.GetUserInput(WindowTitle.EnterMessage20,
|
||||
Main.Settings.WorldVehicleSoftLimit.ToString(), 20));
|
||||
_menuKey.AltTitle = Main.Settings.WorldVehicleSoftLimit.ToString();
|
||||
_vehicleSoftLimit.AltTitle = Main.Settings.WorldVehicleSoftLimit.ToString();
|
||||
Util.SaveSettings();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
private static void PedSoftLimitActivated(object sender, EventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
Main.Settings.WorldPedSoftLimit = int.Parse(
|
||||
Game.GetUserInput(WindowTitle.EnterMessage20,
|
||||
Main.Settings.WorldPedSoftLimit.ToString(), 20));
|
||||
_pedSoftLimit.AltTitle = Main.Settings.WorldPedSoftLimit.ToString();
|
||||
Util.SaveSettings();
|
||||
}
|
||||
catch { }
|
||||
|
@ -30,16 +30,16 @@ namespace RageCoop.Client
|
||||
public static void ToggleConnection(string address, string username = null, string password = null, PublicKey publicKey = null)
|
||||
{
|
||||
Menus.CoopMenu.Menu.Visible = false;
|
||||
Peer?.Shutdown("Bye");
|
||||
if (IsOnServer)
|
||||
{
|
||||
// ?
|
||||
}
|
||||
else if (IsConnecting)
|
||||
if (IsConnecting)
|
||||
{
|
||||
_publicKeyReceived.Set();
|
||||
IsConnecting = false;
|
||||
Notification.Show("Connection has been canceled");
|
||||
Main.QueueAction(() => Notification.Show("Connection has been canceled"));
|
||||
Peer?.Shutdown("Bye");
|
||||
}
|
||||
else if (IsOnServer)
|
||||
{
|
||||
Peer?.Shutdown("Bye");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3,6 +3,7 @@ using Lidgren.Network;
|
||||
using RageCoop.Client.Menus;
|
||||
using RageCoop.Core;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
namespace RageCoop.Client
|
||||
@ -159,6 +160,7 @@ namespace RageCoop.Client
|
||||
Main.Logger.Error(ex);
|
||||
Peer.Shutdown($"Packet Error [{packetType}]");
|
||||
#endif
|
||||
_recycle = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -293,7 +295,7 @@ namespace RageCoop.Client
|
||||
{
|
||||
recycle = false;
|
||||
// Dispatch to script thread
|
||||
Main.QueueAction(() => { SyncEvents.HandleEvent(packetType, msg); Peer.Recycle(msg); return true; });
|
||||
Main.QueueAction(() => { SyncEvents.HandleEvent(packetType, msg); return true; });
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -304,10 +306,14 @@ namespace RageCoop.Client
|
||||
SyncedPed c = EntityPool.GetPedByID(packet.ID);
|
||||
if (c == null)
|
||||
{
|
||||
// Main.Logger.Debug($"Creating character for incoming sync:{packet.ID}");
|
||||
EntityPool.ThreadSafe.Add(c = new SyncedPed(packet.ID));
|
||||
if (EntityPool.PedsByID.Count(x => x.Value.OwnerID == packet.OwnerID) < Main.Settings.WorldPedSoftLimit / PlayerList.Players.Count ||
|
||||
EntityPool.VehiclesByID.Any(x => x.Value.Position.DistanceTo(packet.Position) < 2) || packet.ID == packet.OwnerID)
|
||||
{
|
||||
// Main.Logger.Debug($"Creating character for incoming sync:{packet.ID}");
|
||||
EntityPool.ThreadSafe.Add(c = new SyncedPed(packet.ID));
|
||||
}
|
||||
else return;
|
||||
}
|
||||
PedDataFlags flags = packet.Flags;
|
||||
c.ID = packet.ID;
|
||||
c.OwnerID = packet.OwnerID;
|
||||
c.Health = packet.Health;
|
||||
@ -353,7 +359,13 @@ namespace RageCoop.Client
|
||||
SyncedVehicle v = EntityPool.GetVehicleByID(packet.ID);
|
||||
if (v == null)
|
||||
{
|
||||
EntityPool.ThreadSafe.Add(v = new SyncedVehicle(packet.ID));
|
||||
if (EntityPool.VehiclesByID.Count(x => x.Value.OwnerID == packet.OwnerID) < Main.Settings.WorldVehicleSoftLimit / PlayerList.Players.Count ||
|
||||
EntityPool.PedsByID.Any(x => x.Value.VehicleID == packet.ID || x.Value.Position.DistanceTo(packet.Position) < 2))
|
||||
{
|
||||
// Main.Logger.Debug($"Creating vehicle for incoming sync:{packet.ID}");
|
||||
EntityPool.ThreadSafe.Add(v = new SyncedVehicle(packet.ID));
|
||||
}
|
||||
else return;
|
||||
}
|
||||
if (v.IsLocal) { return; }
|
||||
v.ID = packet.ID;
|
||||
@ -387,7 +399,6 @@ namespace RageCoop.Client
|
||||
}
|
||||
private static void ProjectileSync(Packets.ProjectileSync packet)
|
||||
{
|
||||
|
||||
var p = EntityPool.GetProjectileByID(packet.ID);
|
||||
if (p == null)
|
||||
{
|
||||
|
@ -15,8 +15,8 @@ using System.Resources;
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
|
||||
// Version informationr(
|
||||
[assembly: AssemblyVersion("1.5.4.4")]
|
||||
[assembly: AssemblyFileVersion("1.5.4.4")]
|
||||
// Version information
|
||||
[assembly: AssemblyVersion("1.5.4.7")]
|
||||
[assembly: AssemblyFileVersion("1.5.4.7")]
|
||||
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]
|
||||
|
||||
|
@ -90,7 +90,7 @@
|
||||
<Reference Include="ICSharpCode.SharpZipLib, Version=1.3.3.11, Culture=neutral, PublicKeyToken=1b03e6acf1164f73, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\SharpZipLib.1.3.3\lib\net45\ICSharpCode.SharpZipLib.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="LemonUI.SHVDN3, Version=1.7.0.0, Culture=neutral, processorArchitecture=AMD64">
|
||||
<Reference Include="LemonUI.SHVDN3, Version=1.10.0.0, Culture=neutral, processorArchitecture=AMD64">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\libs\LemonUI.SHVDN3.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -91,7 +91,7 @@ namespace RageCoop.Client.Scripting
|
||||
/// <summary>
|
||||
/// The local player is dead
|
||||
/// </summary>
|
||||
public static event EmptyEvent OnPlayerDied;
|
||||
public static event EventHandler<string> OnPlayerDied;
|
||||
|
||||
/// <summary>
|
||||
/// A local vehicle is spawned
|
||||
@ -133,7 +133,7 @@ namespace RageCoop.Client.Scripting
|
||||
internal static void InvokeVehicleDeleted(SyncedVehicle v) { OnVehicleDeleted?.Invoke(null, v); }
|
||||
internal static void InvokePedSpawned(SyncedPed p) { OnPedSpawned?.Invoke(null, p); }
|
||||
internal static void InvokePedDeleted(SyncedPed p) { OnPedDeleted?.Invoke(null, p); }
|
||||
internal static void InvokePlayerDied() { OnPlayerDied?.Invoke(); }
|
||||
internal static void InvokePlayerDied(string m) { OnPlayerDied?.Invoke(null, m); }
|
||||
internal static void InvokeTick() { OnTick?.Invoke(); }
|
||||
|
||||
internal static void InvokeKeyDown(object s, KeyEventArgs e) { OnKeyDown?.Invoke(s, e); }
|
||||
|
@ -16,7 +16,7 @@ namespace RageCoop.Client.Scripting
|
||||
{
|
||||
API.Events.OnPedDeleted += (s, p) => { API.SendCustomEvent(CustomEvents.OnPedDeleted, p.ID); };
|
||||
API.Events.OnVehicleDeleted += (s, p) => { API.SendCustomEvent(CustomEvents.OnVehicleDeleted, p.ID); };
|
||||
API.Events.OnPlayerDied += () => { API.SendCustomEvent(CustomEvents.OnPlayerDied); };
|
||||
API.Events.OnPlayerDied += (s, m) => { API.SendCustomEvent(CustomEvents.OnPlayerDied, m); };
|
||||
|
||||
API.RegisterCustomEventHandler(CustomEvents.SetAutoRespawn, SetAutoRespawn);
|
||||
API.RegisterCustomEventHandler(CustomEvents.SetDisplayNameTag, SetDisplayNameTag);
|
||||
@ -31,7 +31,7 @@ namespace RageCoop.Client.Scripting
|
||||
API.RegisterCustomEventHandler(CustomEvents.UpdatePedBlip, UpdatePedBlip);
|
||||
API.RegisterCustomEventHandler(CustomEvents.IsHost, (e) => { _isHost = (bool)e.Args[0]; });
|
||||
API.RegisterCustomEventHandler(CustomEvents.WeatherTimeSync, WeatherTimeSync);
|
||||
API.RegisterCustomEventHandler(CustomEvents.OnPlayerDied, (e) => { GTA.UI.Notification.Show($"~h~{e.Args[0]}~h~ died."); });
|
||||
API.RegisterCustomEventHandler(CustomEvents.OnPlayerDied, (e) => { GTA.UI.Notification.Show((string)e.Args[0]); });
|
||||
Task.Run(() =>
|
||||
{
|
||||
while (true)
|
||||
|
@ -67,6 +67,7 @@ namespace RageCoop.Client
|
||||
/// The game won't spawn more NPC traffic if the limit is exceeded. -1 for unlimited (not recommended).
|
||||
/// </summary>
|
||||
public int WorldPedSoftLimit { get; set; } = 30;
|
||||
|
||||
/// <summary>
|
||||
/// The directory where log and resources downloaded from server will be placed.
|
||||
/// </summary>
|
||||
@ -76,5 +77,15 @@ namespace RageCoop.Client
|
||||
/// Show the owner name of the entity you're aiming at
|
||||
/// </summary>
|
||||
public bool ShowEntityOwnerName { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Show other player's nametag on your screen
|
||||
/// </summary>
|
||||
public bool ShowPlayerNameTag { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Show other player's blip on map
|
||||
/// </summary>
|
||||
public bool ShowPlayerBlip { get; set; } = true;
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace RageCoop.Client
|
||||
MainPed = p;
|
||||
OwnerID = Main.LocalPlayerID;
|
||||
|
||||
Function.Call(Hash.SET_PED_IS_IGNORED_BY_AUTO_OPEN_DOORS, 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);
|
||||
|
||||
@ -76,12 +76,13 @@ namespace RageCoop.Client
|
||||
}
|
||||
}
|
||||
|
||||
if (((byte)BlipColor == 255) && (PedBlip != null))
|
||||
if (!Main.Settings.ShowPlayerBlip && (byte)BlipColor != 255) BlipColor = (BlipColor)255;
|
||||
if ((byte)BlipColor == 255 && PedBlip != null)
|
||||
{
|
||||
PedBlip.Delete();
|
||||
PedBlip = null;
|
||||
}
|
||||
else if (((byte)BlipColor != 255) && PedBlip == null)
|
||||
else if ((byte)BlipColor != 255 && PedBlip == null)
|
||||
{
|
||||
PedBlip = MainPed.AddBlip();
|
||||
|
||||
@ -140,6 +141,12 @@ namespace RageCoop.Client
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsPlayer && Health <= 0 && !MainPed.IsDead)
|
||||
{
|
||||
MainPed.Kill();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Speed >= 4)
|
||||
{
|
||||
DisplayInVehicle();
|
||||
@ -170,7 +177,7 @@ namespace RageCoop.Client
|
||||
|
||||
private void RenderNameTag()
|
||||
{
|
||||
if (!Owner.DisplayNameTag || (MainPed == null) || !MainPed.IsVisible || !MainPed.IsInRange(Main.PlayerPosition, 40f))
|
||||
if (!Owner.DisplayNameTag || !Main.Settings.ShowPlayerNameTag || MainPed == null || !MainPed.IsVisible || !MainPed.IsInRange(Main.PlayerPosition, 40f))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@ -204,7 +211,7 @@ namespace RageCoop.Client
|
||||
MainPed = null;
|
||||
}
|
||||
|
||||
if (PedBlip != null && PedBlip.Exists())
|
||||
if (PedBlip != null)
|
||||
{
|
||||
PedBlip.Delete();
|
||||
PedBlip = null;
|
||||
@ -419,7 +426,7 @@ namespace RageCoop.Client
|
||||
}
|
||||
_lastIsJumping = false;
|
||||
|
||||
if (IsRagdoll || Health == 0)
|
||||
if (IsRagdoll || (IsPlayer && Health == 0))
|
||||
{
|
||||
if (!MainPed.IsRagdoll)
|
||||
{
|
||||
@ -597,6 +604,8 @@ namespace RageCoop.Client
|
||||
MainPed.Task.StandStill(2000);
|
||||
LastMoving = false;
|
||||
}
|
||||
|
||||
if (MainPed.IsTaskActive(TaskType.CTaskDiveToGround)) MainPed.Task.ClearAll();
|
||||
break;
|
||||
}
|
||||
SmoothTransition();
|
||||
|
@ -4,6 +4,7 @@ using GTA.Native;
|
||||
using RageCoop.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace RageCoop.Client
|
||||
{
|
||||
@ -307,6 +308,16 @@ namespace RageCoop.Client
|
||||
}
|
||||
private bool CreateVehicle()
|
||||
{
|
||||
var existing = World.GetNearbyVehicles(Position, 2).ToList().FirstOrDefault();
|
||||
if (existing != null && existing != MainVehicle)
|
||||
{
|
||||
if (EntityPool.VehiclesByHandle.ContainsKey(existing.Handle))
|
||||
{
|
||||
EntityPool.RemoveVehicle(ID);
|
||||
return false;
|
||||
}
|
||||
existing.Delete();
|
||||
}
|
||||
MainVehicle?.Delete();
|
||||
MainVehicle = Util.CreateVehicle(Model, Position);
|
||||
if (!Model.IsInCdImage)
|
||||
@ -337,41 +348,5 @@ namespace RageCoop.Client
|
||||
Model.MarkAsNoLongerNeeded();
|
||||
return true;
|
||||
}
|
||||
#region -- PEDALING --
|
||||
/*
|
||||
* Thanks to @oldnapalm.
|
||||
*/
|
||||
|
||||
private string PedalingAnimDict()
|
||||
{
|
||||
switch ((VehicleHash)Model)
|
||||
{
|
||||
case VehicleHash.Bmx:
|
||||
return "veh@bicycle@bmx@front@base";
|
||||
case VehicleHash.Cruiser:
|
||||
return "veh@bicycle@cruiserfront@base";
|
||||
case VehicleHash.Scorcher:
|
||||
return "veh@bicycle@mountainfront@base";
|
||||
default:
|
||||
return "veh@bicycle@roadfront@base";
|
||||
}
|
||||
}
|
||||
|
||||
private string PedalingAnimName(bool fast)
|
||||
{
|
||||
return fast ? "fast_pedal_char" : "cruise_pedal_char";
|
||||
}
|
||||
|
||||
private void StartPedalingAnim(bool fast)
|
||||
{
|
||||
MainVehicle.Driver?.Task.PlayAnimation(PedalingAnimDict(), PedalingAnimName(fast), 8.0f, -8.0f, -1, AnimationFlags.Loop | AnimationFlags.Secondary, 1.0f);
|
||||
|
||||
}
|
||||
|
||||
private void StopPedalingAnim(bool fast)
|
||||
{
|
||||
MainVehicle.Driver.Task.ClearAnimation(PedalingAnimDict(), PedalingAnimName(fast));
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ namespace RageCoop.Client
|
||||
#endregion
|
||||
public static void Cleanup(bool keepPlayer = true, bool keepMine = true)
|
||||
{
|
||||
foreach (var ped in PedsByID.Values)
|
||||
foreach (var ped in PedsByID.Values.ToArray())
|
||||
{
|
||||
if ((keepPlayer && (ped.ID == Main.LocalPlayerID)) || (keepMine && (ped.OwnerID == Main.LocalPlayerID))) { continue; }
|
||||
RemovePed(ped.ID);
|
||||
@ -51,7 +51,7 @@ namespace RageCoop.Client
|
||||
PedsByID.Clear();
|
||||
PedsByHandle.Clear();
|
||||
|
||||
foreach (int id in new List<int>(VehiclesByID.Keys))
|
||||
foreach (int id in VehiclesByID.Keys.ToArray())
|
||||
{
|
||||
if (keepMine && (VehiclesByID[id].OwnerID == Main.LocalPlayerID)) { continue; }
|
||||
RemoveVehicle(id);
|
||||
@ -277,8 +277,8 @@ namespace RageCoop.Client
|
||||
{
|
||||
ProjectilesByHandle.Remove(p.Handle);
|
||||
}
|
||||
Main.Logger.Debug($"Removing projectile {sp.ID}. Reason:{reason}");
|
||||
p.Explode();
|
||||
//Main.Logger.Debug($"Removing projectile {sp.ID}. Reason:{reason}");
|
||||
if (sp.Exploded) p.Explode();
|
||||
}
|
||||
ProjectilesByID.Remove(id);
|
||||
}
|
||||
@ -359,21 +359,24 @@ namespace RageCoop.Client
|
||||
lock (PedsLock)
|
||||
{
|
||||
AddPlayer();
|
||||
var mainCharacters = new List<PedHash> { PedHash.Michael, PedHash.Franklin, PedHash.Franklin02, PedHash.Trevor };
|
||||
|
||||
foreach (Ped p in allPeds)
|
||||
{
|
||||
SyncedPed c = GetPedByHandle(p.Handle);
|
||||
if (c == null && (p != Game.Player.Character))
|
||||
if (!PedsByHandle.ContainsKey(p.Handle) && p != Game.Player.Character && !mainCharacters.Contains((PedHash)p.Model.Hash))
|
||||
{
|
||||
if (allPeds.Length > Main.Settings.WorldPedSoftLimit && p.PopulationType == EntityPopulationType.RandomAmbient && !p.IsInVehicle())
|
||||
if (PedsByID.Count(x => x.Value.IsLocal) > Main.Settings.WorldPedSoftLimit)
|
||||
{
|
||||
p.Delete();
|
||||
continue;
|
||||
if (p.PopulationType == EntityPopulationType.RandomAmbient && !p.IsInVehicle())
|
||||
{
|
||||
p.Delete();
|
||||
continue;
|
||||
}
|
||||
if (p.PopulationType == EntityPopulationType.RandomScenario) continue;
|
||||
}
|
||||
// Main.Logger.Trace($"Creating SyncEntity for ped, handle:{p.Handle}");
|
||||
c = new SyncedPed(p);
|
||||
|
||||
Add(c);
|
||||
Add(new SyncedPed(p));
|
||||
}
|
||||
}
|
||||
#if BENCHMARK
|
||||
@ -437,10 +440,9 @@ namespace RageCoop.Client
|
||||
{
|
||||
if (!VehiclesByHandle.ContainsKey(veh.Handle))
|
||||
{
|
||||
if (allVehicles.Length > Main.Settings.WorldVehicleSoftLimit)
|
||||
if (VehiclesByID.Count(x => x.Value.IsLocal) > Main.Settings.WorldVehicleSoftLimit)
|
||||
{
|
||||
var type = veh.PopulationType;
|
||||
if (type == EntityPopulationType.RandomAmbient || type == EntityPopulationType.RandomParked)
|
||||
if (veh.PopulationType == EntityPopulationType.RandomAmbient || veh.PopulationType == EntityPopulationType.RandomParked)
|
||||
{
|
||||
foreach (var p in veh.Occupants)
|
||||
{
|
||||
|
@ -126,7 +126,7 @@ namespace RageCoop.Client
|
||||
}
|
||||
|
||||
var p = EntityPool.GetPedByID(ownerID)?.MainPed;
|
||||
if (p == null) { p = Game.Player.Character; Main.Logger.Warning("Failed to find owner for bullet"); }
|
||||
if (p == null) { return; /* p = Game.Player.Character; Main.Logger.Warning("Failed to find owner for bullet"); */ }
|
||||
if (!CorePFXAsset.IsLoaded) { CorePFXAsset.Request(); }
|
||||
if (_lastWeaponHash != weaponHash)
|
||||
{
|
||||
|
@ -120,7 +120,7 @@ namespace RageCoop.Client
|
||||
if ((c == null) || (c.IsLocal && (ped.Handle != Game.Player.Character.Handle) && ped.PopulationType != EntityPopulationType.Mission))
|
||||
{
|
||||
|
||||
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();
|
||||
|
@ -15,7 +15,7 @@ using System.Resources;
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Version information
|
||||
[assembly: AssemblyVersion("1.5.4.3")]
|
||||
[assembly: AssemblyFileVersion("1.5.4.3")]
|
||||
[assembly: AssemblyVersion("1.5.4.5")]
|
||||
[assembly: AssemblyFileVersion("1.5.4.5")]
|
||||
[assembly: NeutralResourcesLanguageAttribute( "en-US" )]
|
||||
|
||||
|
@ -38,7 +38,7 @@ namespace RageCoop.Server.Scripting
|
||||
});
|
||||
API.RegisterCustomEventHandler(CustomEvents.OnPlayerDied, (e) =>
|
||||
{
|
||||
API.SendCustomEventQueued(API.GetAllClients().Values.Where(x => x != e.Client).ToList(), CustomEvents.OnPlayerDied, e.Client.Username);
|
||||
API.SendCustomEventQueued(API.GetAllClients().Values.Where(x => x != e.Client).ToList(), CustomEvents.OnPlayerDied, e.Args);
|
||||
});
|
||||
API.Events.OnChatMessage += (s, e) =>
|
||||
Server.Logger?.Info((e.Client?.Username ?? e.ClaimedSender ?? "Unknown") + ": " + e.Message);
|
||||
|
13
docker-compose.yml
Normal file
13
docker-compose.yml
Normal file
@ -0,0 +1,13 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
ragecoop-v:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
ports:
|
||||
- "4499:4499/udp"
|
||||
stdin_open: true
|
||||
tty: true
|
||||
volumes:
|
||||
- ./Settings.xml:/app/Settings.xml
|
Binary file not shown.
Reference in New Issue
Block a user