Files
RAGECOOP-V/RageCoop.Client/Main.cs

396 lines
14 KiB
C#
Raw Normal View History

2022-07-20 17:50:01 +08:00
using GTA;
using GTA.Math;
using GTA.Native;
using RageCoop.Client.Menus;
2022-10-08 12:43:24 +08:00
using RageCoop.Client.Scripting;
2022-07-20 17:50:01 +08:00
using RageCoop.Core;
2022-10-09 22:07:52 +08:00
using SHVDN;
using Script = GTA.Script;
2022-07-20 17:50:01 +08:00
using System;
2022-10-08 12:43:24 +08:00
using System.Collections.Concurrent;
2022-07-20 17:50:01 +08:00
using System.Collections.Generic;
using System.Diagnostics;
2022-08-02 17:43:18 +08:00
using System.Drawing;
2022-09-06 21:46:35 +08:00
using System.IO;
2022-07-21 22:42:29 +08:00
using System.Threading;
2022-09-06 21:46:35 +08:00
using System.Threading.Tasks;
using System.Windows.Forms;
2022-10-09 22:07:52 +08:00
using Console = GTA.Console;
2021-07-07 13:36:25 +02:00
2022-05-22 15:55:26 +08:00
namespace RageCoop.Client
2021-07-07 13:36:25 +02:00
{
2021-12-03 20:30:00 +01:00
/// <summary>
/// Don't use it!
/// </summary>
2022-10-09 22:07:52 +08:00
[ScriptAttributes(Author = "RageCoop", NoDefaultInstance = false, SupportURL = "https://github.com/RAGECOOP/RAGECOOP-V")]
internal class Main : Script
2021-07-07 13:36:25 +02:00
{
2022-10-08 23:49:48 +08:00
public static API API = API.GetInstance();
2022-10-08 12:43:24 +08:00
private static bool _gameLoaded = false;
2022-09-06 21:46:35 +08:00
internal static Version Version = typeof(Main).Assembly.GetName().Version;
2021-07-07 13:36:25 +02:00
2022-07-20 17:50:01 +08:00
internal static int LocalPlayerID = 0;
internal static RelationshipGroup SyncedPedsGroup;
2021-07-07 13:36:25 +02:00
internal static new Settings Settings = null;
2022-10-08 23:49:48 +08:00
internal static BaseScript BaseScript = new BaseScript();
2021-08-18 11:47:59 +02:00
#if !NON_INTERACTIVE
#endif
internal static Chat MainChat = null;
internal static Stopwatch Counter = new Stopwatch();
internal static Logger Logger = null;
internal static ulong Ticked = 0;
internal static Vector3 PlayerPosition;
2022-10-08 23:49:48 +08:00
internal static Resources Resources = null;
2022-10-08 12:43:24 +08:00
private static readonly ConcurrentQueue<Action> TaskQueue = new ConcurrentQueue<Action>();
2022-08-08 17:03:41 +08:00
public static Worker Worker;
2021-12-03 20:30:00 +01:00
/// <summary>
/// Don't use it!
/// </summary>
2021-07-07 13:36:25 +02:00
public Main()
2022-08-27 14:23:28 +08:00
{
2022-10-09 22:07:52 +08:00
Console.WriteLine($"Starting {typeof(Main).FullName}, domain: {AppDomain.CurrentDomain.Id}, {Util.IsPrimaryDomain}");
if (!Util.IsPrimaryDomain) { Console.WriteLine("Ignored loading in scondary domain"); Abort(); return; }
2022-07-14 17:59:41 +08:00
try
{
Settings = Util.ReadSettings();
2022-10-09 22:07:52 +08:00
if (Settings.DataDirectory.StartsWith("Scripts"))
{
var defaultDir = new Settings().DataDirectory;
2022-10-10 16:45:58 +08:00
Console.Warning.WriteLine("Data directory must be outside scripts folder, migrating to default direcoty: " + defaultDir);
2022-10-09 22:07:52 +08:00
if (Directory.Exists(Settings.DataDirectory))
{
CoreUtils.CopyFilesRecursively(new DirectoryInfo(Settings.DataDirectory), new DirectoryInfo(defaultDir));
Directory.Delete(Settings.DataDirectory, true);
}
Settings.DataDirectory = defaultDir;
Util.SaveSettings();
}
2022-07-14 17:59:41 +08:00
}
catch
{
2022-10-08 12:43:24 +08:00
// GTA.UI.Notification.Show("Malformed configuration, overwriting with default values...");
2022-09-06 21:46:35 +08:00
Settings = new Settings();
2022-07-14 17:59:41 +08:00
Util.SaveSettings();
}
2022-07-02 13:53:14 +08:00
Directory.CreateDirectory(Settings.DataDirectory);
2022-09-06 21:46:35 +08:00
Logger = new Logger()
2022-05-31 19:35:01 -08:00
{
2022-09-06 21:46:35 +08:00
LogPath = $"{Settings.DataDirectory}\\RageCoop.Client.log",
UseConsole = false,
2022-05-31 19:35:01 -08:00
#if DEBUG
LogLevel = 0,
#else
2022-10-10 16:45:58 +08:00
LogLevel = Settings.LogLevel,
2022-05-31 19:35:01 -08:00
#endif
};
2022-10-10 16:45:58 +08:00
Logger.OnFlush += (s, d) => Console.WriteLine(d);
2022-10-08 12:43:24 +08:00
Worker = new Worker("RageCoop.Client.Main.Worker", Logger);
2022-10-09 22:07:52 +08:00
ScriptDomain.CurrentDomain.Tick += DomainTick;
2022-10-08 12:43:24 +08:00
Resources = new Resources();
2022-06-22 14:18:20 +08:00
if (Game.Version < GameVersion.v1_0_1290_1_Steam)
{
Tick += (object sender, EventArgs e) =>
{
if (Game.IsLoading)
{
return;
}
if (!_gameLoaded)
{
GTA.UI.Notification.Show("~r~Please update your GTA5 to v1.0.1290 or newer!", true);
_gameLoaded = true;
}
};
return;
2022-06-22 14:18:20 +08:00
}
BaseScript.OnStart();
2022-09-06 21:46:35 +08:00
SyncedPedsGroup = World.AddRelationshipGroup("SYNCPED");
2022-05-22 15:55:26 +08:00
Game.Player.Character.RelationshipGroup.SetRelationshipBetweenGroups(SyncedPedsGroup, Relationship.Neutral, true);
#if !NON_INTERACTIVE
#endif
MainChat = new Chat();
2022-10-08 12:43:24 +08:00
Aborted += OnAborted;
2021-07-07 13:36:25 +02:00
Tick += OnTick;
KeyDown += OnKeyDown;
2022-07-20 17:50:01 +08:00
2021-07-13 16:32:45 +02:00
Util.NativeMemory();
2022-05-22 15:55:26 +08:00
Counter.Restart();
2022-10-08 23:49:48 +08:00
2021-07-07 13:36:25 +02:00
}
2022-10-08 12:43:24 +08:00
private static void OnAborted(object sender, EventArgs e)
{
try
{
2022-10-09 22:07:52 +08:00
WorldThread.Instance?.Abort();
DevTool.Instance?.Abort();
ScriptDomain.CurrentDomain.Tick -= DomainTick;
2022-10-10 16:45:58 +08:00
Disconnected("Abort");
WorldThread.DoQueuedActions();
2022-10-08 12:43:24 +08:00
}
2022-10-08 23:49:48 +08:00
catch (Exception ex)
2022-10-08 12:43:24 +08:00
{
Logger.Error(ex);
}
}
private static void DomainTick(object sender, EventArgs e)
{
2022-10-08 23:49:48 +08:00
while (TaskQueue.TryDequeue(out var task))
2022-10-08 12:43:24 +08:00
{
try
{
task.Invoke();
}
2022-10-08 23:49:48 +08:00
catch (Exception ex)
2022-10-08 12:43:24 +08:00
{
Logger.Error(ex);
}
}
if (Networking.IsOnServer)
{
try
{
EntityPool.DoSync();
}
catch (Exception ex)
{
Logger.Error(ex);
}
}
}
internal static void QueueToMainThread(Action task)
{
TaskQueue.Enqueue(task);
}
2022-07-20 17:50:01 +08:00
public static Ped P;
public static float FPS;
2022-10-08 12:43:24 +08:00
private static bool _lastDead;
private static void OnTick(object sender, EventArgs e)
2021-07-07 13:36:25 +02:00
{
2022-09-06 21:46:35 +08:00
P = Game.Player.Character;
PlayerPosition = P.ReadPosition();
FPS = Game.FPS;
2021-07-07 13:36:25 +02:00
if (Game.IsLoading)
{
return;
}
else if (!_gameLoaded && (_gameLoaded = true))
2021-07-07 13:36:25 +02:00
{
#if !NON_INTERACTIVE
2022-07-20 17:50:01 +08:00
GTA.UI.Notification.Show(GTA.UI.NotificationIcon.AllPlayersConf, "RAGECOOP", "Welcome!", $"Press ~g~{Main.Settings.MenuKey}~s~ to open the menu.");
#endif
2021-07-07 13:36:25 +02:00
}
#if !NON_INTERACTIVE
CoopMenu.MenuPool.Process();
#endif
2022-07-20 17:50:01 +08:00
2022-08-13 11:28:35 +08:00
if (!Networking.IsOnServer)
2021-07-07 13:36:25 +02:00
{
return;
}
2022-09-06 21:46:35 +08:00
if (Game.TimeScale != 1)
2022-04-11 15:10:27 +02:00
{
2022-09-06 21:46:35 +08:00
Game.TimeScale = 1;
2022-04-11 15:10:27 +02:00
}
2022-07-20 17:50:01 +08:00
if (Networking.ShowNetworkInfo)
2021-08-18 11:47:59 +02:00
{
new LemonUI.Elements.ScaledText(new PointF(Screen.PrimaryScreen.Bounds.Width / 2, 0), $"L: {Networking.Latency * 1000:N0}ms", 0.5f) { Alignment = GTA.UI.Alignment.Center }.Draw();
new LemonUI.Elements.ScaledText(new PointF(Screen.PrimaryScreen.Bounds.Width / 2, 30), $"R: {Lidgren.Network.NetUtility.ToHumanReadable(Statistics.BytesDownPerSecond)}/s", 0.5f) { Alignment = GTA.UI.Alignment.Center }.Draw();
new LemonUI.Elements.ScaledText(new PointF(Screen.PrimaryScreen.Bounds.Width / 2, 60), $"S: {Lidgren.Network.NetUtility.ToHumanReadable(Statistics.BytesUpPerSecond)}/s", 0.5f) { Alignment = GTA.UI.Alignment.Center }.Draw();
2021-08-18 11:47:59 +02:00
}
2022-05-22 15:55:26 +08:00
2021-07-07 13:36:25 +02:00
MainChat.Tick();
PlayerList.Tick();
2022-10-08 12:43:24 +08:00
if (!API.Config.EnableAutoRespawn)
{
Function.Call(Hash.PAUSE_DEATH_ARREST_RESTART, true);
2022-06-22 14:18:20 +08:00
Function.Call(Hash.IGNORE_NEXT_RESTART, true);
2022-07-20 17:50:01 +08:00
Function.Call(Hash.FORCE_GAME_STATE_PLAYING);
2022-06-22 14:18:20 +08:00
Function.Call(Hash.TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME, "respawn_controller");
if (P.IsDead)
{
Function.Call(Hash.SET_FADE_OUT_AFTER_DEATH, false);
2022-07-20 17:50:01 +08:00
2022-09-06 21:46:35 +08:00
if (P.Health != 1)
{
2022-09-06 21:46:35 +08:00
P.Health = 1;
Game.Player.WantedLevel = 0;
2022-10-08 12:43:24 +08:00
Logger.Debug("Player died.");
API.Events.InvokePlayerDied();
}
GTA.UI.Screen.StopEffects();
}
else
{
Function.Call(Hash.DISPLAY_HUD, true);
}
}
else if (P.IsDead && !_lastDead)
{
2022-10-08 23:49:48 +08:00
API.Events.InvokePlayerDied();
}
2022-09-06 21:46:35 +08:00
_lastDead = P.IsDead;
2022-05-22 15:55:26 +08:00
Ticked++;
2021-07-07 13:36:25 +02:00
}
2022-10-08 12:43:24 +08:00
private static void OnKeyDown(object sender, KeyEventArgs e)
2021-07-07 13:36:25 +02:00
{
2022-08-13 02:19:40 +02:00
if (MainChat.Focused)
{
MainChat.OnKeyDown(e.KeyCode);
return;
}
if (Networking.IsOnServer)
2022-08-13 00:52:34 +02:00
{
2022-08-15 16:13:53 +08:00
if (Voice.WasInitialized())
2022-08-13 00:52:34 +02:00
{
2022-08-13 03:39:11 +02:00
if (Game.IsControlPressed(GTA.Control.PushToTalk))
{
2022-08-15 16:13:53 +08:00
Voice.StartRecording();
2022-08-13 03:39:11 +02:00
return;
}
2022-08-15 16:13:53 +08:00
else if (Voice.IsRecording())
2022-08-13 03:39:11 +02:00
{
2022-08-15 16:13:53 +08:00
Voice.StopRecording();
2022-08-13 03:39:11 +02:00
return;
}
2022-08-13 00:52:34 +02:00
}
2022-09-06 21:46:35 +08:00
if (Game.IsControlPressed(GTA.Control.FrontendPause))
{
Function.Call(Hash.ACTIVATE_FRONTEND_MENU, Function.Call<int>(Hash.GET_HASH_KEY, "FE_MENU_VERSION_SP_PAUSE"), false, 0);
return;
}
2022-09-06 21:46:35 +08:00
if (Game.IsControlPressed(GTA.Control.FrontendPauseAlternate) && Settings.DisableAlternatePause)
{
Function.Call(Hash.ACTIVATE_FRONTEND_MENU, Function.Call<int>(Hash.GET_HASH_KEY, "FE_MENU_VERSION_SP_PAUSE"), false, 0);
return;
}
}
if (e.KeyCode == Settings.MenuKey)
2022-05-22 15:55:26 +08:00
{
if (CoopMenu.MenuPool.AreAnyVisible)
{
CoopMenu.MenuPool.ForEach<LemonUI.Menus.NativeMenu>(x =>
{
if (x.Visible)
{
2022-09-06 21:46:35 +08:00
CoopMenu.LastMenu = x;
x.Visible = false;
}
});
}
else
{
CoopMenu.LastMenu.Visible = true;
}
2022-05-22 15:55:26 +08:00
}
else if (Game.IsControlJustPressed(GTA.Control.MpTextChatAll))
{
if (Networking.IsOnServer)
{
MainChat.Focused = true;
}
}
2022-08-16 22:23:32 +08:00
else if (MainChat.Focused) { return; }
else if (Game.IsControlJustPressed(GTA.Control.MultiplayerInfo))
2022-05-22 15:55:26 +08:00
{
if (Networking.IsOnServer)
{
ulong currentTimestamp = Util.GetTickCount64();
PlayerList.Pressed = (currentTimestamp - PlayerList.Pressed) < 5000 ? (currentTimestamp - 6000) : currentTimestamp;
}
2022-05-22 15:55:26 +08:00
}
2022-09-06 21:46:35 +08:00
else if (e.KeyCode == Settings.PassengerKey)
2022-05-22 15:55:26 +08:00
{
var P = Game.Player.Character;
2022-07-20 17:50:01 +08:00
if (!P.IsInVehicle())
2022-05-22 15:55:26 +08:00
{
2022-05-23 13:02:28 +08:00
if (P.IsTaskActive(TaskType.CTaskEnterVehicle))
2022-05-22 15:55:26 +08:00
{
P.Task.ClearAll();
2022-05-22 15:55:26 +08:00
}
else
2022-05-22 15:55:26 +08:00
{
var V = World.GetClosestVehicle(P.ReadPosition(), 50);
2022-09-06 21:46:35 +08:00
if (V != null)
{
var seat = P.GetNearestSeat(V);
2022-08-21 14:12:44 +08:00
var p = V.GetPedOnSeat(seat);
if (p != null && !p.IsDead)
{
2022-09-06 21:46:35 +08:00
for (int i = -1; i < V.PassengerCapacity; i++)
2022-08-21 14:12:44 +08:00
{
seat = (VehicleSeat)i;
p = V.GetPedOnSeat(seat);
if (p == null || p.IsDead)
{
break;
}
}
}
2022-09-06 21:46:35 +08:00
P.Task.EnterVehicle(V, seat, -1, 5, EnterVehicleFlags.None);
}
2022-05-22 15:55:26 +08:00
}
}
}
2021-07-07 13:36:25 +02:00
}
2022-09-06 21:46:35 +08:00
internal static void Connected()
{
Memory.ApplyPatches();
if (Settings.Voice && !Voice.WasInitialized())
{
Voice.Init();
}
2022-10-09 11:15:09 +08:00
API.QueueAction(() =>
2022-09-06 21:46:35 +08:00
{
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)
{
2022-09-06 21:46:35 +08:00
Logger.Info($">> Disconnected << reason: {reason}");
2022-10-09 11:15:09 +08:00
API.QueueAction(() =>
2022-09-06 21:46:35 +08:00
{
if (MainChat.Focused)
{
MainChat.Focused = false;
}
PlayerList.Cleanup();
2022-09-06 21:46:35 +08:00
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;
2022-10-10 16:45:58 +08:00
Resources.Unload();
2022-09-06 21:46:35 +08:00
});
Memory.RestorePatches();
DownloadManager.Cleanup();
Voice.ClearAll();
}
2022-05-22 15:55:26 +08:00
2022-09-06 21:46:35 +08:00
2021-07-07 13:36:25 +02:00
}
}