using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Mirror;
using Steamworks;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("FleesDedicatedServer")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.0.6.0")]
[assembly: AssemblyInformationalVersion("0.0.6+65c99c8fe79e4bd8ea8cb1d47e86b27549f52da9")]
[assembly: AssemblyProduct("Atlyss_Server")]
[assembly: AssemblyTitle("FleesDedicatedServer")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace AtlyssDedicatedServer
{
[BepInPlugin("FleesDedicatedServer", "Atlyss_Server", "0.0.6")]
[BepInProcess("ATLYSS.exe")]
public class Plugin : BaseUnityPlugin, ILogListener, IDisposable
{
public enum LobbyTypeTag : byte
{
PUBLIC,
FRIENDS,
PRIVATE
}
[HarmonyPatch(typeof(ChatBehaviour), "New_ChatMessage")]
private class ChatMirrorPatch
{
private static void Postfix(string _message)
{
if (isProcessingConsoleCommand)
{
isProcessingConsoleCommand = false;
return;
}
string text = StripUnityRichText(_message);
if (!(text == lastServerMessage) || !((DateTime.UtcNow - lastServerMessageTime).TotalMilliseconds < 100.0))
{
Console.WriteLine("[Chat] " + text);
}
}
private static string StripUnityRichText(string input)
{
return Regex.Replace(input, "<.*?>", string.Empty);
}
}
[HarmonyPatch(typeof(HostConsole), "New_LogMessage")]
private class HostConsoleFixPatch
{
private static bool Prefix(string _message)
{
string arg = $"[{DateTime.Now.Hour}:{DateTime.Now.Minute}] " + _message;
lastServerMessage = _message;
lastServerMessageTime = DateTime.UtcNow;
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("{0}", arg);
Console.ResetColor();
return false;
}
}
[HarmonyPatch(typeof(AtlyssNetworkManager), "Console_GetInput")]
private class ConsolePatch
{
private static readonly StringBuilder inputBuffer = new StringBuilder();
internal static readonly object consoleLock = new object();
private static bool Prefix()
{
if (!Console.KeyAvailable)
{
return false;
}
ConsoleKeyInfo consoleKeyInfo = Console.ReadKey(intercept: true);
lock (consoleLock)
{
switch (consoleKeyInfo.Key)
{
case ConsoleKey.Enter:
{
string text = inputBuffer.ToString();
inputBuffer.Clear();
_rawConsoleOut.WriteLine();
isProcessingConsoleCommand = true;
HostConsole._current.Send_ServerMessage(text);
RedrawInput();
break;
}
case ConsoleKey.Backspace:
if (inputBuffer.Length > 0)
{
inputBuffer.Length--;
RedrawInput();
}
break;
default:
if (!char.IsControl(consoleKeyInfo.KeyChar))
{
inputBuffer.Append(consoleKeyInfo.KeyChar);
_rawConsoleOut.Write(consoleKeyInfo.KeyChar);
}
break;
}
}
return false;
}
internal static void RedrawInput()
{
string text = "> ";
string value = text + inputBuffer.ToString();
ClearInputLine();
_rawConsoleOut.Write(value);
}
internal static void ClearInputLine()
{
int windowWidth = Console.WindowWidth;
_rawConsoleOut.Write("\r" + new string(' ', windowWidth - 1) + "\r");
}
}
[HarmonyPatch(typeof(HostConsole), "Send_ServerMessage")]
private class ChatManagerPatch
{
private static bool Prefix(ref string _message)
{
if (!string.IsNullOrWhiteSpace(_message))
{
HostConsole obj = Object.FindObjectOfType<HostConsole>();
FieldInfo fieldInfo = AccessTools.Field(typeof(HostConsole), "_cmdManager");
object value = fieldInfo.GetValue(obj);
string[] array = _message.Split(' ');
if (_message.Contains('<') || _message.Contains('>'))
{
Logger.LogInfo((object)"'<' and '>' are not allowed in server messages.");
return false;
}
if (_message[0] == '/')
{
AccessTools.Method(value.GetType(), "Init_ConsoleCommand", (Type[])null, (Type[])null)?.Invoke(value, new object[2]
{
array[0].TrimStart('/'),
(array.Length > 1) ? array[1] : string.Empty
});
}
else
{
AccessTools.Method(typeof(HostConsole), "Init_ServerMessage", new Type[1] { typeof(string) }, (Type[])null)?.Invoke(obj, new object[1] { _message });
}
}
return false;
}
}
[HarmonyPatch(typeof(SettingsManager), "Handle_AudioParameters")]
private class AudioParamsPatch
{
private static bool Prefix(SettingsManager __instance)
{
AudioListener.volume = 0f;
return false;
}
}
[HarmonyPatch(typeof(NetworkManager), "StopHost")]
public class StopHostPatch
{
private static void Postfix(NetworkManager __instance)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
Debug.Log((object)"[StopHostPatch] Host stopped. Scheduling shutdown in 5 seconds.");
GameObject val = new GameObject("ShutdownScheduler");
Object.DontDestroyOnLoad((Object)(object)val);
val.AddComponent<ShutdownDelay>();
}
}
public class ShutdownDelay : MonoBehaviour
{
[CompilerGenerated]
private sealed class <DelayedShutdown>d__1 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public ShutdownDelay <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DelayedShutdown>d__1(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(5f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
Debug.Log((object)"[ShutdownDelay] Shutting down game...");
Application.Quit();
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private void Start()
{
((MonoBehaviour)this).StartCoroutine(DelayedShutdown());
}
[IteratorStateMachine(typeof(<DelayedShutdown>d__1))]
private IEnumerator DelayedShutdown()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DelayedShutdown>d__1(0)
{
<>4__this = this
};
}
}
private string serverName = "ATLYSS Server";
private LobbyTypeTag serverType = LobbyTypeTag.PUBLIC;
private AtlyssSteamLobbyTag serverTag = (AtlyssSteamLobbyTag)0;
private string serverPassword = string.Empty;
private string serverMOTD = string.Empty;
private int serverMaxPlayers = 16;
private int hostCharSaveSlot = 0;
private bool shouldHostServer = false;
private bool hostSpawned = false;
private bool actionTriggered = false;
private float timeSinceSpawn = 0f;
private string playerName = string.Empty;
internal static ManualLogSource Logger;
private ILogListener _bepinexConsoleListener;
private static TextWriter _rawConsoleOut;
internal static string lastServerMessage = string.Empty;
internal static DateTime lastServerMessageTime;
public static bool isProcessingConsoleCommand = false;
private bool detected = false;
private string GetArgValue(string[] args, string key)
{
int num = Array.IndexOf(args, key);
return (num >= 0 && num + 1 < args.Length) ? args[num + 1] : null;
}
private void LogServerConfig()
{
//IL_0057: Unknown result type (might be due to invalid IL or missing references)
Logger.LogInfo((object)"=== Server Configuration ===");
Logger.LogInfo((object)("Server Name : " + serverName));
Logger.LogInfo((object)$"Server Type : {serverType}");
Logger.LogInfo((object)$"Server Tag : {serverTag}");
Logger.LogInfo((object)("Server Password : " + (string.IsNullOrEmpty(serverPassword) ? "[None]" : serverPassword)));
Logger.LogInfo((object)("Server MOTD : " + (string.IsNullOrEmpty(serverMOTD) ? "[None]" : serverMOTD)));
Logger.LogInfo((object)$"Max Players : {serverMaxPlayers}");
Logger.LogInfo((object)"============================");
}
private void Awake()
{
//IL_043b: Unknown result type (might be due to invalid IL or missing references)
//IL_04ca: Unknown result type (might be due to invalid IL or missing references)
//IL_04a0: Unknown result type (might be due to invalid IL or missing references)
//IL_04a5: Unknown result type (might be due to invalid IL or missing references)
//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
//IL_04bf: Unknown result type (might be due to invalid IL or missing references)
//IL_04aa: Unknown result type (might be due to invalid IL or missing references)
//IL_04af: Unknown result type (might be due to invalid IL or missing references)
//IL_04b4: Unknown result type (might be due to invalid IL or missing references)
Logger = ((BaseUnityPlugin)this).Logger;
Logger.LogInfo((object)"Plugin FleesDedicatedServer is loaded!");
if (!Application.isBatchMode)
{
Logger.LogWarning((object)"Not running in batchmode, DedicatedServer plugin exiting.");
return;
}
Console.CursorVisible = true;
try
{
Type type = Type.GetType("BepInEx.ConsoleManager, BepInEx");
if (type == null)
{
Logger.LogError((object)"Failed to find BepInEx.ConsoleManager type.");
return;
}
PropertyInfo property = type.GetProperty("StandardOutStream", BindingFlags.Static | BindingFlags.Public);
if (property != null)
{
_rawConsoleOut = (TextWriter)property.GetValue(null, null);
}
if (_rawConsoleOut == null)
{
Logger.LogError((object)"Failed to get raw console output stream via reflection.");
}
else
{
try
{
List<ILogListener> source = (List<ILogListener>)typeof(Logger).GetProperty("Listeners", BindingFlags.Static | BindingFlags.Public).GetValue(null);
_bepinexConsoleListener = ((IEnumerable<ILogListener>)source).FirstOrDefault((Func<ILogListener, bool>)((ILogListener l) => ((object)l).GetType().Name == "ConsoleLogListener"));
if (_bepinexConsoleListener != null)
{
Logger.Listeners.Remove(_bepinexConsoleListener);
Logger.LogInfo((object)"Successfully detached default BepInEx console listener.");
}
Logger.Listeners.Add((ILogListener)(object)this);
}
catch (Exception arg)
{
Logger.LogError((object)$"An error occurred while detaching listener: {arg}");
}
}
}
catch (Exception arg2)
{
Logger.LogError((object)$"An error occurred while accessing the console stream: {arg2}");
}
string[] commandLineArgs = Environment.GetCommandLineArgs();
if (!commandLineArgs.Contains("-server"))
{
return;
}
Logger.LogInfo((object)"Starting in dedicated server mode.");
shouldHostServer = true;
Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
if (int.TryParse(GetArgValue(commandLineArgs, "-hostsave"), out var result))
{
if (result >= 0 && result <= 104)
{
hostCharSaveSlot = result;
}
else
{
hostCharSaveSlot = 0;
Logger.LogWarning((object)"HostSave must be between 0 and 104. Defaulting to 0.");
}
}
else
{
hostCharSaveSlot = 0;
}
serverName = GetArgValue(commandLineArgs, "-name") ?? "ATLYSS Server";
if (serverName.Length > 20)
{
Logger.LogWarning((object)$"Server name \"{serverName}\" is too long ({serverName.Length}/20). Defaulting to \"ATLYSS Server\".");
serverName = "ATLYSS Server";
}
serverPassword = GetArgValue(commandLineArgs, "-password") ?? "";
serverMOTD = GetArgValue(commandLineArgs, "-motd") ?? "Welcome to the server!";
List<string> list = new string[3] { "-public", "-private", "-friends" }.Where(((IEnumerable<string>)commandLineArgs).Contains<string>).ToList();
if (list.Count > 1)
{
Logger.LogWarning((object)("Multiple server type flags detected (" + string.Join(", ", list) + "). Defaulting to PUBLIC."));
serverType = LobbyTypeTag.PUBLIC;
}
else if (list.Count == 1)
{
string text = list[0];
if (1 == 0)
{
}
LobbyTypeTag lobbyTypeTag = text switch
{
"-public" => LobbyTypeTag.PUBLIC,
"-private" => LobbyTypeTag.PRIVATE,
"-friends" => LobbyTypeTag.FRIENDS,
_ => LobbyTypeTag.PUBLIC,
};
if (1 == 0)
{
}
serverType = lobbyTypeTag;
}
else
{
serverType = LobbyTypeTag.PUBLIC;
}
List<string> list2 = new string[4] { "-pve", "-pvp", "-social", "-rp" }.Where(((IEnumerable<string>)commandLineArgs).Contains<string>).ToList();
if (list2.Count > 1)
{
Logger.LogWarning((object)("Multiple lobby focus flags detected (" + string.Join(", ", list2) + "). Defaulting to PVE."));
serverTag = (AtlyssSteamLobbyTag)0;
}
else if (list2.Count == 1)
{
string text2 = list2[0];
if (1 == 0)
{
}
AtlyssSteamLobbyTag val = (AtlyssSteamLobbyTag)(text2 switch
{
"-pve" => 0,
"-pvp" => 1,
"-social" => 2,
"-rp" => 3,
_ => 0,
});
if (1 == 0)
{
}
serverTag = val;
}
else
{
serverTag = (AtlyssSteamLobbyTag)0;
}
if (int.TryParse(GetArgValue(commandLineArgs, "-maxplayers"), out var result2))
{
if (result2 >= 2 && result2 <= 250)
{
serverMaxPlayers = result2;
}
else
{
serverMaxPlayers = 16;
Logger.LogWarning((object)"MaxPlayers must be between 2 and 250. Defaulting to 16.");
}
}
else
{
serverMaxPlayers = 16;
}
LogServerConfig();
}
private void Update()
{
if (!shouldHostServer)
{
return;
}
if (!hostSpawned)
{
if ((Object)(object)NetworkClient.localPlayer != (Object)null)
{
hostSpawned = true;
Logger.LogInfo((object)"[HostSpawnDetector] Host player spawned. Starting delay...");
}
}
else if (!actionTriggered)
{
timeSinceSpawn += Time.deltaTime;
if (timeSinceSpawn >= 30f)
{
actionTriggered = true;
OnHostReady();
}
}
if (!detected && (Object)(object)Object.FindObjectOfType<MainMenuManager>() != (Object)null)
{
detected = true;
HostServer();
}
}
private void OnHostReady()
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
Logger.LogInfo((object)"[HostSpawnDetector] 30 seconds passed since host spawned — teleporting!");
Player component = GameObject.Find("[connID: 0] _player(" + playerName + ")").GetComponent<Player>();
CharacterController component2 = ((Component)component).GetComponent<CharacterController>();
((Collider)component2).enabled = false;
((Component)component).transform.SetPositionAndRotation(new Vector3(500f, 50f, 510f), new Quaternion(0f, 0f, 0f, 0f));
((Collider)component2).enabled = true;
}
private void HostServer()
{
//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_0132: Unknown result type (might be due to invalid IL or missing references)
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_013c: Unknown result type (might be due to invalid IL or missing references)
//IL_0170: Unknown result type (might be due to invalid IL or missing references)
Logger.LogInfo((object)"[DedicatedServer] Hosting Server");
ServerHostSettings_Profile hostSettingsProfile = ProfileDataManager._current._hostSettingsProfile;
AtlyssNetworkManager current = AtlyssNetworkManager._current;
ProfileDataManager current2 = ProfileDataManager._current;
LobbyListManager current3 = LobbyListManager._current;
current._steamworksMode = true;
current._soloMode = false;
current._serverMode = false;
current._serverName = serverName;
current._serverPassword = serverPassword;
current._sentPassword = serverPassword;
current._serverMotd = serverMOTD;
((NetworkManager)current).maxConnections = serverMaxPlayers;
current3._lobbyPasswordInput.text = current._serverPassword;
current3._lobbyTypeDropdown.value = (int)serverType;
current3._hostLobbyRealm = serverTag;
current._bannedClientList.Clear();
current._mutedClientList.Clear();
if (hostSettingsProfile._banList != null)
{
current._bannedClientList.AddRange(hostSettingsProfile._banList);
}
if (hostSettingsProfile._mutedList != null)
{
current._mutedClientList.AddRange(hostSettingsProfile._mutedList);
}
ELobbyType val = (ELobbyType)2;
switch ((int)serverType)
{
case 0:
val = (ELobbyType)2;
break;
case 1:
val = (ELobbyType)1;
break;
case 2:
val = (ELobbyType)0;
break;
}
playerName = current2._characterFiles[hostCharSaveSlot]._nickName;
current2._characterFile = current2._characterFiles[hostCharSaveSlot];
SteamLobby._current.HostLobby(val);
MainMenuManager._current._characterSelectManager.Send_CharacterFile();
}
public void LogEvent(object sender, LogEventArgs e)
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
if (e.Source.SourceName == "INPUT")
{
return;
}
lock (ConsolePatch.consoleLock)
{
ConsolePatch.ClearInputLine();
string value = $"[{e.Level,-7}:{e.Source.SourceName}] {e.Data}";
_rawConsoleOut.WriteLine(value);
ConsolePatch.RedrawInput();
}
}
public void Dispose()
{
Logger.Listeners.Remove((ILogListener)(object)this);
Logger.Listeners.Add(_bepinexConsoleListener);
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "FleesDedicatedServer";
public const string PLUGIN_NAME = "Atlyss_Server";
public const string PLUGIN_VERSION = "0.0.6";
}
}