MSCO 2.9.0: standalone without MSCLoader (Unity Doorstop)
- Bootstrap: Doorstop entry point, loads Harmony/Newtonsoft from the MSCO folder, hooks PlayMakerArrayListProxy.Awake and starts MSCO in the main menu; skips the news screen - No MSCLoader reference anymore; key bindings in PlayerPrefs, bind console command - Harmony 1.2 and Newtonsoft.Json in lib/ (MIT notices); build copies to <game>\MSCO - README/CHANGELOG updated Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+143
@@ -0,0 +1,143 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using Harmony;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Doorstop
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Einstieg ohne MSCLoader: Unity Doorstop (winhttp.dll im Spielordner) ruft beim Spielstart diese Methode auf - der
|
||||||
|
/// MSCO Launcher startet das Spiel mit "--doorstop-target-assembly ...\MSCO\MSCO.dll", MSCLoader wird dann gar nicht
|
||||||
|
/// geladen. Hier läuft noch nichts von Unity: nur vorbereiten, gestartet wird im Hauptmenü (siehe MSCO.Bootstrap).
|
||||||
|
/// </summary>
|
||||||
|
public static class Entrypoint
|
||||||
|
{
|
||||||
|
public static void Start()
|
||||||
|
{
|
||||||
|
MSCO.Bootstrap.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MSCO
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Startet MSCO eigenständig: Abhängigkeiten (Harmony, Newtonsoft.Json) aus dem MSCO-Ordner laden, warten bis das
|
||||||
|
/// Spiel seinen Code geladen hat, dann beim ersten PlayMakerArrayListProxy.Awake (Hauptmenü, Hauptthread) den
|
||||||
|
/// MultiplayerManager anlegen. Protokoll: <Spiel>\MSCO\MSCO_Loader.txt.
|
||||||
|
/// </summary>
|
||||||
|
public static class Bootstrap
|
||||||
|
{
|
||||||
|
static string folder;
|
||||||
|
static bool patched, started;
|
||||||
|
static StreamWriter log;
|
||||||
|
|
||||||
|
public static void Start()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
folder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||||
|
log = new StreamWriter(Path.Combine(folder, "MSCO_Loader.txt"), false) { AutoFlush = true };
|
||||||
|
Log("MSCO " + MSCO.ModVersion + " loader started (standalone, without MSCLoader)");
|
||||||
|
Log("Command line: " + string.Join(" ", Environment.GetCommandLineArgs()));
|
||||||
|
AppDomain.CurrentDomain.AssemblyResolve += Resolve;
|
||||||
|
AppDomain.CurrentDomain.AssemblyLoad += (_, e) => OnAssemblyLoaded(e.LoadedAssembly);
|
||||||
|
foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies()) OnAssemblyLoaded(a);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Log("Loader failed: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Log(string line)
|
||||||
|
{
|
||||||
|
try { if (log != null) log.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " " + line); } catch { }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Unsere Abhängigkeiten liegen neben MSCO.dll (das Spiel sucht nur in Managed).</summary>
|
||||||
|
static Assembly Resolve(object sender, ResolveEventArgs args)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string name = new AssemblyName(args.Name).Name;
|
||||||
|
string file = Path.Combine(folder, name + ".dll");
|
||||||
|
if (File.Exists(file)) return Assembly.LoadFrom(file);
|
||||||
|
}
|
||||||
|
catch (Exception e) { Log("Resolve " + args.Name + " failed: " + e.Message); }
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void OnAssemblyLoaded(Assembly assembly)
|
||||||
|
{
|
||||||
|
if (patched) return;
|
||||||
|
string name;
|
||||||
|
try { name = assembly.GetName().Name; } catch { return; }
|
||||||
|
if (name != "Assembly-CSharp") return;
|
||||||
|
patched = true;
|
||||||
|
try { Patch(assembly); }
|
||||||
|
catch (Exception e) { Log("Could not hook into the game: " + e); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Haken in PlayMakerArrayListProxy.Awake (läuft im Hauptmenü früh auf dem Hauptthread).</summary>
|
||||||
|
static void Patch(Assembly game)
|
||||||
|
{
|
||||||
|
Type proxy = game.GetType("PlayMakerArrayListProxy");
|
||||||
|
MethodInfo awake = proxy != null ? proxy.GetMethod("Awake", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) : null;
|
||||||
|
if (awake == null)
|
||||||
|
{
|
||||||
|
Log("PlayMakerArrayListProxy.Awake not found - MSCO cannot start");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
HarmonyInstance.Create("mbm.msco.bootstrap").Patch(awake,
|
||||||
|
new HarmonyMethod(typeof(Bootstrap).GetMethod("BeforeAwake", BindingFlags.Static | BindingFlags.NonPublic)), null);
|
||||||
|
Log("Hooked into the game, waiting for the main menu");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void BeforeAwake()
|
||||||
|
{
|
||||||
|
if (started) return;
|
||||||
|
started = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var go = new GameObject("MSCO_Host");
|
||||||
|
UnityEngine.Object.DontDestroyOnLoad(go);
|
||||||
|
go.AddComponent<MscoHost>();
|
||||||
|
Log("MSCO started");
|
||||||
|
}
|
||||||
|
catch (Exception e) { Log("Start failed: " + e); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Lebt über alle Szenen: legt im Hauptmenü den MultiplayerManager an (früher MSCLoaders OnMenuLoad).</summary>
|
||||||
|
public class MscoHost : MonoBehaviour
|
||||||
|
{
|
||||||
|
void Start()
|
||||||
|
{
|
||||||
|
MscoLog.Info("Welcome to MSCO by mbm.wtf");
|
||||||
|
// Den Nachrichten-Bildschirm des Spiels ("Latest news ... press any key") überspringen - direkt ins Hauptmenü
|
||||||
|
string scene = Application.loadedLevelName;
|
||||||
|
Bootstrap.Log("First scene: " + scene);
|
||||||
|
if (scene != "MainMenu" && scene != "GAME")
|
||||||
|
{
|
||||||
|
Bootstrap.Log("Skipping the intro/news screen");
|
||||||
|
Application.LoadLevel("MainMenu");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MultiplayerManager.Ensure();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnLevelWasLoaded(int level)
|
||||||
|
{
|
||||||
|
Bootstrap.Log("Level loaded: " + Application.loadedLevelName);
|
||||||
|
MultiplayerManager.Ensure();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnApplicationQuit()
|
||||||
|
{
|
||||||
|
// Wer beendet das Spiel? (Diagnose)
|
||||||
|
Bootstrap.Log("Game is quitting (scene " + Application.loadedLevelName + "): " + System.Environment.StackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -6,7 +6,7 @@ namespace MSCO
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// MSCO-Logo (branding/logo-128.png, als Ressource in die DLL eingebettet):
|
/// MSCO-Logo (branding/logo-128.png, als Ressource in die DLL eingebettet):
|
||||||
/// Symbol in der MSCLoader-Modliste und im Launcher.
|
/// Symbol im MSCO-Launcher (Hauptmenü) und in Overlays.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Branding
|
public static class Branding
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2.9.0
|
||||||
|
|
||||||
|
**Eigenständig – ohne MSCLoader**
|
||||||
|
- MSCO braucht MSCLoader nicht mehr: es startet selbst über Unity Doorstop (`winhttp.dll`) aus `<Spielordner>\MSCO`.
|
||||||
|
Der MSCO Launcher richtet alles ein und stellt `doorstop_config.ini` auf MSCO um – auch der Start über Steam lädt dann
|
||||||
|
MSCO. MSCLoader ist dabei blockiert (seine Konfiguration wird als `doorstop_config.mscloader.ini` gesichert)
|
||||||
|
- Der Nachrichten-Bildschirm beim Spielstart („Press any key“) wird übersprungen, MSCO öffnet direkt im Hauptmenü
|
||||||
|
- Tasten ändern jetzt mit `bind` in der F7-Konsole (`bind passenger O`), gespeichert in den Spiel-Einstellungen
|
||||||
|
- Harmony und Newtonsoft.Json liegen neben `MSCO.dll`; Lade-Protokoll in `MSCO\MSCO_Loader.txt`
|
||||||
|
- `msco://`-Links werden vom Launcher übernommen, wenn er installiert ist
|
||||||
|
- Netzwerk-Version bleibt 2.8: spielt mit 2.8.x-Servern und -Mitspielern
|
||||||
|
|
||||||
## 2.8.1
|
## 2.8.1
|
||||||
|
|
||||||
**Mehr Events synchron**
|
**Mehr Events synchron**
|
||||||
|
|||||||
+19
-1
@@ -1,10 +1,11 @@
|
|||||||
|
using UnityEngine;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Alle MSCO-Befehle an einer Stelle - genutzt von der eigenen F7-Konsole (ohne "mp" davor)
|
/// Alle MSCO-Befehle an einer Stelle - genutzt von der eigenen F7-Konsole (ohne "mp" davor)
|
||||||
/// und von der MSCLoader-Konsole ("mp ...").
|
/// (früher auch aus der MSCLoader-Konsole - MSCO läuft jetzt ohne MSCLoader).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Commands
|
public static class Commands
|
||||||
{
|
{
|
||||||
@@ -17,6 +18,7 @@ namespace MSCO
|
|||||||
"disconnect - leave the server / game\n" +
|
"disconnect - leave the server / game\n" +
|
||||||
"host [port] / join <ip> [port] - direct LAN game (no Steam)\n" +
|
"host [port] / join <ip> [port] - direct LAN game (no Steam)\n" +
|
||||||
"save - save the game (host / singleplayer)\n" +
|
"save - save the game (host / singleplayer)\n" +
|
||||||
|
"bind [action key] - show / change keys (passenger, console, chat)\n" +
|
||||||
"ping [on|off] - show your ping to the server (toggle)\n" +
|
"ping [on|off] - show your ping to the server (toggle)\n" +
|
||||||
"fps [on|off] - show the frames per second (toggle)\n" +
|
"fps [on|off] - show the frames per second (toggle)\n" +
|
||||||
"/admin - admin menu (kick / ban / teleport / cheats)\n" +
|
"/admin - admin menu (kick / ban / teleport / cheats)\n" +
|
||||||
@@ -115,6 +117,22 @@ namespace MSCO
|
|||||||
else mp.ShowPing = !mp.ShowPing;
|
else mp.ShowPing = !mp.ShowPing;
|
||||||
print("Ping: " + mp.PingText + " (display " + (mp.ShowPing ? "on" : "off") + ")");
|
print("Ping: " + mp.PingText + " (display " + (mp.ShowPing ? "on" : "off") + ")");
|
||||||
break;
|
break;
|
||||||
|
case "bind":
|
||||||
|
{
|
||||||
|
// Tasten ändern: "bind" zeigt alle, "bind passenger O" setzt eine (früher MSCLoader-Einstellungen)
|
||||||
|
if (args.Length < 3)
|
||||||
|
{
|
||||||
|
foreach (KeyBinding k in MSCO.Keys) print(" " + k.Id.PadRight(10) + " " + k.Key + " (" + k.Description + ", default " + k.Default + ")");
|
||||||
|
print("Change: bind <" + string.Join("|", System.Array.ConvertAll(MSCO.Keys, k => k.Id)) + "> <key> e.g. bind passenger O");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
KeyBinding target = System.Array.Find(MSCO.Keys, k => k.Id.Equals(args[1], System.StringComparison.OrdinalIgnoreCase));
|
||||||
|
KeyCode key;
|
||||||
|
if (target == null) print("Unknown action " + args[1] + " - see 'bind'");
|
||||||
|
else if (!KeyBinding.TryParse(args[2], out key)) print("Unknown key " + args[2] + " (Unity key names, e.g. O, F6, Keypad5, Mouse3)");
|
||||||
|
else { target.Key = key; print(target.Description + ": " + key); }
|
||||||
|
break;
|
||||||
|
}
|
||||||
case "fps":
|
case "fps":
|
||||||
// "fps" schaltet die Anzeige um, "fps on/off" setzt sie
|
// "fps" schaltet die Anzeige um, "fps on/off" setzt sie
|
||||||
if (args.Length > 1) mp.ShowFps = args[1].ToLower() == "on" || args[1] == "1";
|
if (args.Length > 1) mp.ShowFps = args[1].ToLower() == "on" || args[1] == "1";
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using MSCLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using HutongGames.PlayMaker;
|
using HutongGames.PlayMaker;
|
||||||
using MSCLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using System.IO;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Harmony;
|
using Harmony;
|
||||||
using HutongGames.PlayMaker;
|
using HutongGames.PlayMaker;
|
||||||
using MSCLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Harmony;
|
using Harmony;
|
||||||
using MSCLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
|
|||||||
+7
-1
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using MSCLoader;
|
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
{
|
{
|
||||||
@@ -31,6 +30,13 @@ namespace MSCO
|
|||||||
}
|
}
|
||||||
string command = "\"" + steamExe + "\" -applaunch " + MySummerCarAppId + " " + Argument + " \"%1\"";
|
string command = "\"" + steamExe + "\" -applaunch " + MySummerCarAppId + " " + Argument + " \"%1\"";
|
||||||
|
|
||||||
|
// Ist der MSCO Launcher installiert, gehören die Links ihm: er startet das Spiel mit MSCO (ohne MSCLoader)
|
||||||
|
using (RegistryKey existing = Registry.CurrentUser.OpenSubKey(@"Software\Classes\" + Scheme + @"\shell\open\command"))
|
||||||
|
{
|
||||||
|
string current = existing != null ? existing.GetValue("") as string : null;
|
||||||
|
if (current != null && current.IndexOf("MSCO-Launcher", StringComparison.OrdinalIgnoreCase) >= 0) return;
|
||||||
|
}
|
||||||
|
|
||||||
using (RegistryKey key = Registry.CurrentUser.CreateSubKey(@"Software\Classes\" + Scheme))
|
using (RegistryKey key = Registry.CurrentUser.CreateSubKey(@"Software\Classes\" + Scheme))
|
||||||
{
|
{
|
||||||
key.SetValue("", "URL:MSCO Join Link");
|
key.SetValue("", "URL:MSCO Join Link");
|
||||||
|
|||||||
@@ -1,22 +1,24 @@
|
|||||||
using MSCLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
{
|
{
|
||||||
public class MSCO : Mod
|
/// <summary>
|
||||||
|
/// MSCO - My Summer Car Online. Läuft eigenständig (ohne MSCLoader): gestartet über Unity Doorstop, siehe Bootstrap.
|
||||||
|
/// </summary>
|
||||||
|
public static class MSCO
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Version der Mod (MSCLoader / MSC Launcher). Kleine Updates: nur die dritte Stelle erhöhen (2.8.1, 2.8.2 ...) -
|
/// Version der Mod. Kleine Updates: nur die dritte Stelle erhöhen (2.9.1, 2.9.2 ...) - sie bleiben mit
|
||||||
/// sie bleiben mit 2.8-Servern und -Mitspielern kompatibel.
|
/// Servern und Mitspielern derselben ersten zwei Stellen kompatibel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string ModVersion = "2.8.1";
|
public const string ModVersion = "2.9.0";
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Netzwerk-Version (die ersten beiden Stellen). Nur erhöhen, wenn sich das Protokoll inkompatibel ändert - dann
|
/// Netzwerk-Version (die ersten beiden Stellen). Nur erhöhen, wenn sich das Protokoll inkompatibel ändert - dann
|
||||||
/// auch GameServer.ModVersion im Server und eine neue Mod-Version 2.9.0 o.ä.
|
/// auch GameServer.ModVersion im Server.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public const string ProtocolVersion = "2.8";
|
public const string ProtocolVersion = "2.8";
|
||||||
|
|
||||||
/// <summary>Passt eine andere Version (Server, Host, Mitspieler) zu uns? Verglichen werden nur die ersten zwei Stellen.</summary>
|
/// <summary>Passt eine andere Version (Server, Host, Mitspieler) zu uns? Verglichen wird die Netzwerk-Version.</summary>
|
||||||
public static bool Compatible(string other)
|
public static bool Compatible(string other)
|
||||||
{
|
{
|
||||||
return Protocol(other) == ProtocolVersion;
|
return Protocol(other) == ProtocolVersion;
|
||||||
@@ -30,78 +32,67 @@ namespace MSCO
|
|||||||
return parts.Length >= 2 ? parts[0] + "." + parts[1] : version.Trim();
|
return parts.Length >= 2 ? parts[0] + "." + parts[1] : version.Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ID => "MSCO"; // Your (unique) mod ID
|
/// <summary>Beifahrer ein-/aussteigen (Standard P), Konsole (F7), Chat (T) - änderbar mit "bind" in der Konsole.</summary>
|
||||||
public override string Name => "MSCO"; // Your mod name
|
internal static readonly KeyBinding PassengerKey = new KeyBinding("passenger", "Ride along / get out", KeyCode.P);
|
||||||
public override string Author => "MBM"; // Name of the Author (your name)
|
internal static readonly KeyBinding ConsoleKey = new KeyBinding("console", "Open the MSCO console", KeyCode.F7);
|
||||||
public override string Version => ModVersion; // Version
|
internal static readonly KeyBinding ChatKey = new KeyBinding("chat", "Open the chat", KeyCode.T);
|
||||||
public override string Description => "Online mod by mbm.wtf"; // Short description of your mod
|
internal static readonly KeyBinding[] Keys = { PassengerKey, ConsoleKey, ChatKey };
|
||||||
public override Game SupportedGames => Game.MySummerCar;
|
|
||||||
// Logo in der MSCLoader-Modliste (branding/logo-128.png, in die DLL eingebettet)
|
|
||||||
public override byte[] Icon { get { return Branding.LogoPng; } set { } }
|
|
||||||
|
|
||||||
bool commandAdded;
|
|
||||||
|
|
||||||
public override void ModSetup()
|
|
||||||
{
|
|
||||||
SetupFunction(Setup.OnMenuLoad, Mod_OnMenuLoad);
|
|
||||||
SetupFunction(Setup.OnLoad, Mod_OnLoad);
|
|
||||||
SetupFunction(Setup.PostLoad, Mod_PostLoad);
|
|
||||||
SetupFunction(Setup.OnSave, Mod_OnSave);
|
|
||||||
SetupFunction(Setup.OnGUI, Mod_OnGUI);
|
|
||||||
SetupFunction(Setup.Update, Mod_Update);
|
|
||||||
SetupFunction(Setup.FixedUpdate, Mod_FixedUpdate);
|
|
||||||
SetupFunction(Setup.ModSettings, Mod_Settings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Taste zum Ein-/Aussteigen als Beifahrer (in den MSCLoader-Einstellungen änderbar).</summary>
|
/// <summary>Tastenbelegung, gespeichert in den PlayerPrefs (früher in den MSCLoader-Einstellungen).</summary>
|
||||||
internal static SettingsKeybind PassengerKey;
|
public class KeyBinding
|
||||||
/// <summary>MSCO-Konsole (Standard F7) und Chat (Standard T), ebenfalls änderbar.</summary>
|
|
||||||
internal static SettingsKeybind ConsoleKey, ChatKey;
|
|
||||||
|
|
||||||
private void Mod_Settings()
|
|
||||||
{
|
{
|
||||||
// All settings should be created here.
|
public readonly string Id, Description;
|
||||||
// DO NOT put anything that isn't settings or keybinds in here!
|
public readonly KeyCode Default;
|
||||||
PassengerKey = Keybind.Add("passenger", "Ride as passenger (toggle)", KeyCode.P);
|
bool loaded;
|
||||||
ChatKey = Keybind.Add("chat", "Open chat", KeyCode.T);
|
KeyCode key;
|
||||||
// Nicht F8: im Pausenmenü öffnet F8 ein Test-Menü des Spiels. Neue ID, damit alte F8-Belegungen nicht übernommen werden
|
|
||||||
ConsoleKey = Keybind.Add("console_f7", "Open MSCO console", KeyCode.F7);
|
public KeyBinding(string id, string description, KeyCode defaultKey)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
Description = description;
|
||||||
|
Default = defaultKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Mod_OnMenuLoad()
|
string Pref { get { return "MSCO_Key_" + Id; } }
|
||||||
|
|
||||||
|
public KeyCode Key
|
||||||
{
|
{
|
||||||
MscoLog.Info("Welcome to MSCO by mbm.wtf");
|
get
|
||||||
// Netzwerk + Lobby leben in einem eigenen Objekt, das Szenenwechsel überlebt
|
|
||||||
MultiplayerManager.Ensure();
|
|
||||||
if (!commandAdded)
|
|
||||||
{
|
{
|
||||||
ConsoleCommand.Add(new MpCommand());
|
if (!loaded)
|
||||||
commandAdded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void Mod_OnLoad()
|
|
||||||
{
|
{
|
||||||
// Called once, when mod is loading after game is fully loaded
|
// Erst im Spiel lesen (PlayerPrefs gehen nicht in statischen Initialisierern)
|
||||||
|
KeyCode parsed;
|
||||||
|
key = TryParse(PlayerPrefs.GetString(Pref, ""), out parsed) ? parsed : Default;
|
||||||
|
loaded = true;
|
||||||
}
|
}
|
||||||
private void Mod_PostLoad()
|
return key;
|
||||||
|
}
|
||||||
|
set
|
||||||
{
|
{
|
||||||
// Called once, after all mods finished OnLoad
|
key = value;
|
||||||
|
loaded = true;
|
||||||
|
PlayerPrefs.SetString(Pref, value.ToString());
|
||||||
|
PlayerPrefs.Save();
|
||||||
}
|
}
|
||||||
private void Mod_OnSave()
|
}
|
||||||
|
|
||||||
|
public bool GetKeybindDown()
|
||||||
{
|
{
|
||||||
// Called once, when save and quit
|
return Key != KeyCode.None && Input.GetKeyDown(Key);
|
||||||
}
|
}
|
||||||
private void Mod_OnGUI()
|
|
||||||
|
public static bool TryParse(string text, out KeyCode key)
|
||||||
{
|
{
|
||||||
// Lobby/Status zeichnet der MultiplayerManager
|
key = KeyCode.None;
|
||||||
}
|
if (string.IsNullOrEmpty(text)) return false;
|
||||||
private void Mod_Update()
|
try
|
||||||
{
|
{
|
||||||
// Netzwerk läuft im MultiplayerManager
|
key = (KeyCode)System.Enum.Parse(typeof(KeyCode), text.Trim(), true);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
private void Mod_FixedUpdate()
|
catch { return false; }
|
||||||
{
|
|
||||||
// FixedUpdate is called once per fixed frame
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-35
@@ -42,12 +42,8 @@
|
|||||||
<HintPath>F:\SteamLibrary\steamapps\common\My Summer Car\mysummercar_Data\Managed\UnityEngine.dll</HintPath>
|
<HintPath>F:\SteamLibrary\steamapps\common\My Summer Car\mysummercar_Data\Managed\UnityEngine.dll</HintPath>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="MSCLoader">
|
|
||||||
<HintPath>F:\SteamLibrary\steamapps\common\My Summer Car\mysummercar_Data\Managed\MSCLoader.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Newtonsoft.Json">
|
<Reference Include="Newtonsoft.Json">
|
||||||
<HintPath>F:\SteamLibrary\steamapps\common\My Summer Car\mysummercar_Data\Managed\Newtonsoft.Json.dll</HintPath>
|
<HintPath>lib\Newtonsoft.Json.dll</HintPath>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Assembly-CSharp-firstpass">
|
<Reference Include="Assembly-CSharp-firstpass">
|
||||||
@@ -67,7 +63,7 @@
|
|||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="0Harmony">
|
<Reference Include="0Harmony">
|
||||||
<HintPath>F:\SteamLibrary\steamapps\common\My Summer Car\mysummercar_Data\Managed\0Harmony.dll</HintPath>
|
<HintPath>lib\0Harmony.dll</HintPath>
|
||||||
<Private>False</Private>
|
<Private>False</Private>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -82,7 +78,7 @@
|
|||||||
<Compile Include="Toasts.cs" />
|
<Compile Include="Toasts.cs" />
|
||||||
<Compile Include="PlayerNeeds.cs" />
|
<Compile Include="PlayerNeeds.cs" />
|
||||||
<Compile Include="Favorites.cs" />
|
<Compile Include="Favorites.cs" />
|
||||||
<Compile Include="MpCommand.cs" />
|
<Compile Include="Bootstrap.cs" />
|
||||||
<Compile Include="Commands.cs" />
|
<Compile Include="Commands.cs" />
|
||||||
<Compile Include="MscoLog.cs" />
|
<Compile Include="MscoLog.cs" />
|
||||||
<Compile Include="ItemSpawner.cs" />
|
<Compile Include="ItemSpawner.cs" />
|
||||||
@@ -120,35 +116,11 @@
|
|||||||
<Compile Include="RemotePlayer.cs" />
|
<Compile Include="RemotePlayer.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<PropertyGroup>
|
|
||||||
<MSCMODSFOLDER>C:\Users\nico\Documents\MySummerCar\Mods</MSCMODSFOLDER>
|
|
||||||
<MWCMODSFOLDER>NONE</MWCMODSFOLDER>
|
|
||||||
<ABFOLDER>NONE</ABFOLDER>
|
|
||||||
<PostBuildEvent>
|
|
||||||
echo .
|
|
||||||
echo "== Running post build actions for configuration $(ConfigurationName)! ==="
|
|
||||||
|
|
||||||
IF "$(ConfigurationName)" == "Release" (
|
<!-- Zum Testen: MSCO.dll direkt in den Spielordner (My Summer Car\MSCO) - läuft das Spiel, ist sie gesperrt -->
|
||||||
IF NOT "$(MSCMODSFOLDER)" == "NONE" (
|
<Target Name="CopyToGame" AfterTargets="Build">
|
||||||
copy "$(TargetPath)" "$(MSCMODSFOLDER)" /y
|
<Copy SourceFiles="$(TargetPath)" DestinationFolder="F:\SteamLibrary\steamapps\common\My Summer Car\MSCO" ContinueOnError="true" Condition="Exists('F:\SteamLibrary\steamapps\common\My Summer Car')" />
|
||||||
echo "Copied dll into MSC mods folder!"
|
</Target>
|
||||||
)
|
|
||||||
IF NOT "$(MWCMODSFOLDER)" == "NONE" (
|
|
||||||
copy "$(TargetPath)" "$(MWCMODSFOLDER)" /y
|
|
||||||
echo "Copied dll into MWC mods folder!"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if "$(ConfigurationName)" == "Debug" (
|
|
||||||
copy "$(TargetPath)" "C:\Users\nico\Documents\MySummerCar\Mods" /y
|
|
||||||
copy "$(TargetDir)$(TargetName).pdb" "C:\Users\nico\Documents\MySummerCar\Mods" /y
|
|
||||||
cd "C:\Users\nico\Documents\MySummerCar\Mods"
|
|
||||||
call "C:\Users\nico\Documents\MySummerCar\Mods\debug.bat"
|
|
||||||
) ELSE (
|
|
||||||
copy "$(TargetPath)" "C:\Users\nico\Documents\MySummerCar\Mods\Mods" /y
|
|
||||||
)
|
|
||||||
</PostBuildEvent>
|
|
||||||
</PropertyGroup>
|
|
||||||
<!-- Release-Build: neue Version automatisch auf den Keymaster laden (nur mit Release-Token, siehe release.ps1) -->
|
<!-- Release-Build: neue Version automatisch auf den Keymaster laden (nur mit Release-Token, siehe release.ps1) -->
|
||||||
<Target Name="MscoRelease" AfterTargets="Build" Condition="'$(Configuration)' == 'Release'">
|
<Target Name="MscoRelease" AfterTargets="Build" Condition="'$(Configuration)' == 'Release'">
|
||||||
<Exec Command="powershell -NoProfile -ExecutionPolicy Bypass -File "$(MSBuildProjectDirectory)\release.ps1" -Product mod -File "$(TargetPath)"" ContinueOnError="true" />
|
<Exec Command="powershell -NoProfile -ExecutionPolicy Bypass -File "$(MSBuildProjectDirectory)\release.ps1" -Product mod -File "$(TargetPath)"" ContinueOnError="true" />
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using HutongGames.PlayMaker;
|
using HutongGames.PlayMaker;
|
||||||
using HutongGames.PlayMaker.Actions;
|
using HutongGames.PlayMaker.Actions;
|
||||||
using MSCLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
using MSCLoader;
|
|
||||||
|
|
||||||
namespace MSCO
|
|
||||||
{
|
|
||||||
/// <summary>MSCLoader-Konsole: "mp <befehl>" - gleiche Befehle wie in der F7-Konsole.</summary>
|
|
||||||
public class MpCommand : ConsoleCommand
|
|
||||||
{
|
|
||||||
public override string Name => "mp";
|
|
||||||
public override string Help => "MSCO commands, e.g. mp help | mp connect <host[:port]> | mp save (or press F7)";
|
|
||||||
|
|
||||||
public override void Run(string[] args)
|
|
||||||
{
|
|
||||||
Commands.Execute(args, line => ModConsole.Print("[MSCO] " + line));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+1
-1
@@ -4,7 +4,7 @@ using UnityEngine;
|
|||||||
namespace MSCO
|
namespace MSCO
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Zentrales Log der Mod: alle Meldungen landen in der MSCO-Konsole (F7), nicht in der MSCLoader-Konsole.
|
/// Zentrales Log der Mod: alle Meldungen landen in der MSCO-Konsole (F7), nicht in einer Loader-Konsole.
|
||||||
/// Zusätzlich gehen sie per Debug.Log in die output_log.txt des Spiels (zur Fehlersuche), ohne dass sich die
|
/// Zusätzlich gehen sie per Debug.Log in die output_log.txt des Spiels (zur Fehlersuche), ohne dass sich die
|
||||||
/// MSCLoader-Konsole öffnet. Thread-sicher: Meldungen aus Hintergrund-Threads werden im Hauptthread übernommen.
|
/// MSCLoader-Konsole öffnet. Thread-sicher: Meldungen aus Hintergrund-Threads werden im Hauptthread übernommen.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using HutongGames.PlayMaker;
|
using HutongGames.PlayMaker;
|
||||||
using MSCLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
@@ -1103,7 +1102,7 @@ namespace MSCO
|
|||||||
public string DisconnectNotice { get; private set; }
|
public string DisconnectNotice { get; private set; }
|
||||||
|
|
||||||
// ---------------------------------------------------------------- Über Neuladen hinweg merken
|
// ---------------------------------------------------------------- Über Neuladen hinweg merken
|
||||||
// Beim Wechsel ins Hauptmenü lädt MSCLoader alle Mods neu - dabei ginge der Kick-Grund bzw. "bitte neu
|
// Beim Wechsel ins Hauptmenü wird die Sitzung neu aufgebaut - dabei ginge der Kick-Grund bzw. "bitte neu
|
||||||
// verbinden" verloren, bevor man das Menü überhaupt sieht. Deshalb in den PlayerPrefs sichern.
|
// verbinden" verloren, bevor man das Menü überhaupt sieht. Deshalb in den PlayerPrefs sichern.
|
||||||
const string PrefNotice = "MSCO_PendingNotice";
|
const string PrefNotice = "MSCO_PendingNotice";
|
||||||
const string PrefReconnect = "MSCO_PendingReconnect";
|
const string PrefReconnect = "MSCO_PendingReconnect";
|
||||||
@@ -1339,7 +1338,7 @@ namespace MSCO
|
|||||||
if (wasClientInGame)
|
if (wasClientInGame)
|
||||||
{
|
{
|
||||||
SetStatus("Disconnected from host: " + reason);
|
SetStatus("Disconnected from host: " + reason);
|
||||||
PersistPendingState(); // MSCLoader lädt die Mods im Menü neu - vorher sichern
|
PersistPendingState(); // das Menü baut alles neu auf - vorher sichern
|
||||||
Application.LoadLevel(MenuHelper.MenuScene);
|
Application.LoadLevel(MenuHelper.MenuScene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2422,7 +2421,7 @@ namespace MSCO
|
|||||||
overlays.Draw(this, session != null);
|
overlays.Draw(this, session != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>F7 Konsole, T Chat (Tasten in den MSCLoader-Einstellungen änderbar).</summary>
|
/// <summary>F7 Konsole, T Chat (Tasten mit "bind" in der Konsole änderbar).</summary>
|
||||||
void UpdateOverlayKeys()
|
void UpdateOverlayKeys()
|
||||||
{
|
{
|
||||||
if (MSCO.ConsoleKey != null && MSCO.ConsoleKey.GetKeybindDown()) overlays.ToggleConsole();
|
if (MSCO.ConsoleKey != null && MSCO.ConsoleKey.GetKeybindDown()) overlays.ToggleConsole();
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using HutongGames.PlayMaker;
|
using HutongGames.PlayMaker;
|
||||||
using MSCLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ using System.Runtime.InteropServices;
|
|||||||
// Please disclose yourself when generating code for this project
|
// Please disclose yourself when generating code for this project
|
||||||
// Put "Generated By: {AI model name}" in AssemblyTrademark("") field
|
// Put "Generated By: {AI model name}" in AssemblyTrademark("") field
|
||||||
[assembly: AssemblyTitle("MSCO")]
|
[assembly: AssemblyTitle("MSCO")]
|
||||||
[assembly: AssemblyDescription("MSCLoader Mod file")]
|
[assembly: AssemblyDescription("MSCO - My Summer Car Online (standalone, Unity Doorstop)")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("MBM")]
|
[assembly: AssemblyCompany("MBM")]
|
||||||
[assembly: AssemblyProduct("MSCO")]
|
[assembly: AssemblyProduct("MSCO")]
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
# MSCO – My Summer Car Online
|
# MSCO – My Summer Car Online
|
||||||
|
|
||||||
Multiplayer-Mod für **My Summer Car** (MSCLoader). Spiel mit bis zu 3 Spielern zusammen – per Steam-Einladung
|
Multiplayer-Mod für **My Summer Car**. Spiel mit bis zu 3 Spielern zusammen – per Steam-Einladung (P2P) oder auf
|
||||||
(P2P) oder auf einem dedizierten Server aus dem Server-Browser.
|
einem dedizierten Server aus dem Server-Browser. MSCO läuft **eigenständig, ohne MSCLoader** (Start über
|
||||||
|
[Unity Doorstop](https://github.com/NeighTools/UnityDoorstop)); MSCLoader wird beim Spielen mit MSCO blockiert.
|
||||||
|
|
||||||
- Mod: dieses Repository
|
- Mod: dieses Repository
|
||||||
- Dedizierter Server: [MSCO-Dedicated-Server](https://git.mbm.wtf/MrMaho/MSCO-Dedicated-Server)
|
- Dedizierter Server: [MSCO-Dedicated-Server](https://git.mbm.wtf/MrMaho/MSCO-Dedicated-Server)
|
||||||
@@ -49,20 +50,32 @@ Multiplayer-Mod für **My Summer Car** (MSCLoader). Spiel mit bis zu 3 Spielern
|
|||||||
GOTO/BRING (teleportieren), Cheats (+1.000 / +10.000 MK, Bedürfnisse auffüllen, Satsuma zu sich holen), Items spawnen,
|
GOTO/BRING (teleportieren), Cheats (+1.000 / +10.000 MK, Bedürfnisse auffüllen, Satsuma zu sich holen), Items spawnen,
|
||||||
Welt zurücksetzen/Backups – Cheats werden im Chat angezeigt
|
Welt zurücksetzen/Backups – Cheats werden im Chat angezeigt
|
||||||
- **P** / **Leertaste** – aussteigen; **P** neben einem Auto – auf den Beifahrersitz
|
- **P** / **Leertaste** – aussteigen; **P** neben einem Auto – auf den Beifahrersitz
|
||||||
- Alle Tasten sind in den MSCLoader-Einstellungen der Mod änderbar
|
- Tasten ändern mit `bind` in der F7-Konsole (z.B. `bind passenger O`)
|
||||||
- Rich Presence: zeigt Freunden deinen Status („In the Menus“, Server, Spielerzahl)
|
- Rich Presence: zeigt Freunden deinen Status („In the Menus“, Server, Spielerzahl)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
**Mit dem Launcher (empfohlen):** den [MSCO Launcher](https://msco.mbm.wtf/download) installieren – er installiert
|
**Mit dem Launcher (empfohlen):** den [MSCO Launcher](https://msco.mbm.wtf/download) installieren – er installiert
|
||||||
und aktualisiert MSCO und startet das Spiel. [MSCLoader](https://github.com/piotrulos/MSCModLoader) muss installiert sein.
|
und aktualisiert MSCO und startet das Spiel. MSCLoader wird **nicht** gebraucht.
|
||||||
|
|
||||||
**Von Hand:**
|
Was der Launcher im Spielordner einrichtet:
|
||||||
|
|
||||||
1. [MSCLoader](https://github.com/piotrulos/MSCModLoader) installieren.
|
| Datei | |
|
||||||
2. `MSCO.dll` von der [Download-Seite](https://msco.mbm.wtf/download) laden und in den Mods-Ordner kopieren
|
|---|---|
|
||||||
(Standard: `Documents\MySummerCar\Mods`).
|
| `MSCO\MSCO.dll` (+ `0Harmony.dll`, `Newtonsoft.Json.dll`) | die Mod |
|
||||||
3. Spiel **über Steam** starten – ohne Steam gehen nur Non-Steam-Server.
|
| `winhttp.dll` | Unity Doorstop 4 – nur wenn noch keiner da ist (MSCLoader bringt denselben mit) |
|
||||||
|
| `doorstop_config.ini` | zeigt auf `MSCO\MSCO.dll` – eine MSCLoader-Konfiguration wird vorher als `doorstop_config.mscloader.ini` gesichert |
|
||||||
|
|
||||||
|
Alte MSCO-Versionen im MSCLoader-Mods-Ordner werden in `MSCO.dll.old` umbenannt. Damit startet My Summer Car auch über
|
||||||
|
Steam mit MSCO und ohne MSCLoader. **MSCLoader wieder benutzen:** `doorstop_config.mscloader.ini` zurück in
|
||||||
|
`doorstop_config.ini` umbenennen.
|
||||||
|
|
||||||
|
**Von Hand:** Doorstop 4 (`winhttp.dll`, x64) in den Spielordner, `MSCO.dll` von der
|
||||||
|
[Download-Seite](https://msco.mbm.wtf/download) mit `0Harmony.dll` und `Newtonsoft.Json.dll` nach
|
||||||
|
`<Spielordner>\MSCO\` und in `doorstop_config.ini` `target_assembly = MSCO\MSCO.dll` eintragen.
|
||||||
|
|
||||||
|
Spiel **mit Steam** starten – ohne Steam gehen nur Non-Steam-Server. Das Lade-Protokoll steht in
|
||||||
|
`<Spielordner>\MSCO\MSCO_Loader.txt`.
|
||||||
|
|
||||||
### Einen eigenen Server betreiben
|
### Einen eigenen Server betreiben
|
||||||
|
|
||||||
@@ -77,12 +90,14 @@ unter https://msco.mbm.wtf/keys.
|
|||||||
| „This server requires Steam“ | Spiel über Steam starten |
|
| „This server requires Steam“ | Spiel über Steam starten |
|
||||||
| Warnung „Version mismatch“ | Die ersten zwei Stellen unterscheiden sich – Mod (Launcher) oder Server aktualisieren |
|
| Warnung „Version mismatch“ | Die ersten zwei Stellen unterscheiden sich – Mod (Launcher) oder Server aktualisieren |
|
||||||
| Mod lässt sich nicht aktualisieren | Spiel schließen – solange es läuft, ist `MSCO.dll` gesperrt |
|
| Mod lässt sich nicht aktualisieren | Spiel schließen – solange es läuft, ist `MSCO.dll` gesperrt |
|
||||||
|
| Statt MSCO startet MSCLoader | Im Launcher **SPIELEN** drücken – er stellt `doorstop_config.ini` wieder auf MSCO (z.B. nach einem MSCLoader-Update) |
|
||||||
|
| MSCO startet gar nicht | `<Spielordner>\MSCO\MSCO_Loader.txt` ansehen |
|
||||||
| Eigener Spielstand weg | Wird nach dem Verlassen automatisch wiederhergestellt; Sicherung liegt in `AppData\LocalLow\Amistech\My Summer Car\MSCO_Backup` |
|
| Eigener Spielstand weg | Wird nach dem Verlassen automatisch wiederhergestellt; Sicherung liegt in `AppData\LocalLow\Amistech\My Summer Car\MSCO_Backup` |
|
||||||
| Absturz / Hänger beim Beitreten | `output_log.txt` im Spielordner an den Server-Betreiber bzw. als Issue schicken |
|
| Absturz / Hänger beim Beitreten | `output_log.txt` im Spielordner an den Server-Betreiber bzw. als Issue schicken |
|
||||||
|
|
||||||
## Befehle
|
## Befehle
|
||||||
|
|
||||||
In der F7-Konsole direkt, in der MSCLoader-Konsole mit `mp` davor (z.B. `mp connect ...`):
|
In der F7-Konsole:
|
||||||
|
|
||||||
| Befehl | Beschreibung |
|
| Befehl | Beschreibung |
|
||||||
|---|---|
|
|---|---|
|
||||||
@@ -98,38 +113,40 @@ In der F7-Konsole direkt, in der MSCLoader-Konsole mit `mp` davor (z.B. `mp conn
|
|||||||
| `admin` bzw. `/admin` im Chat | Admin-Menü |
|
| `admin` bzw. `/admin` im Chat | Admin-Menü |
|
||||||
| `vehicles`, `rig` | Diagnose: Fahrzeuge / Spielermodelle |
|
| `vehicles`, `rig` | Diagnose: Fahrzeuge / Spielermodelle |
|
||||||
| `debug` | Sync-Debugausgaben an/aus |
|
| `debug` | Sync-Debugausgaben an/aus |
|
||||||
|
| `bind [aktion taste]` | Tasten anzeigen / ändern (`passenger`, `console`, `chat`) |
|
||||||
| `clear` | Konsole leeren |
|
| `clear` | Konsole leeren |
|
||||||
|
|
||||||
## Selbst bauen
|
## Selbst bauen
|
||||||
|
|
||||||
- Eine C#-Entwicklungsumgebung, .NET Framework 3.5 (Unity 5.0 / Mono)
|
- Eine C#-Entwicklungsumgebung, .NET Framework 3.5 (Unity 5.0 / Mono)
|
||||||
- Die Verweise in `MSCO.csproj` zeigen auf `F:\SteamLibrary\steamapps\common\My Summer Car\mysummercar_Data\Managed\`
|
- Die Verweise in `MSCO.csproj` zeigen auf `F:\SteamLibrary\steamapps\common\My Summer Car\mysummercar_Data\Managed\`
|
||||||
(UnityEngine, PlayMaker, Assembly-CSharp, Assembly-CSharp-firstpass, MSCLoader, 0Harmony, Newtonsoft.Json, cInput) –
|
(UnityEngine, PlayMaker, Assembly-CSharp, Assembly-CSharp-firstpass, cInput) – bei anderem Installationsort anpassen.
|
||||||
bei anderem Installationsort anpassen.
|
Harmony 1.2 und Newtonsoft.Json liegen in `lib/` (MIT, siehe `lib/THIRD-PARTY.txt`).
|
||||||
- Nach dem Build wird die DLL automatisch nach `Documents\MySummerCar\Mods` kopiert (`MSCMODSFOLDER` in der csproj).
|
- Nach dem Build wird die DLL automatisch nach `<Spielordner>\MSCO` kopiert (Ziel `CopyToGame` in der csproj).
|
||||||
|
- Einstieg: `Bootstrap.cs` (`Doorstop.Entrypoint.Start` → Harmony-Haken in `PlayMakerArrayListProxy.Awake` → `MSCO_Host`
|
||||||
|
im Hauptmenü, überspringt den Nachrichten-Bildschirm).
|
||||||
|
|
||||||
```
|
```
|
||||||
msbuild MSCO.csproj -p:Configuration=Release
|
msbuild MSCO.csproj -p:Configuration=Release
|
||||||
```
|
```
|
||||||
|
|
||||||
### Updates veröffentlichen (MSC Launcher / MSCLoader)
|
### Updates veröffentlichen
|
||||||
|
|
||||||
- **Kleines Update** (Fehlerbehebungen, neue Funktionen, Netzwerk unverändert): in `MSCO.cs` nur die dritte Stelle von
|
- **Kleines Update** (Fehlerbehebungen, neue Funktionen, Netzwerk unverändert): in `MSCO.cs` nur die dritte Stelle von
|
||||||
`ModVersion` erhöhen (`2.8.1` → `2.8.2`), Release bauen und `bin/Release/MSCO.dll` hochladen. Spieler mit 2.8.x
|
`ModVersion` erhöhen (`2.9.0` → `2.9.1`), Release bauen und `bin/Release/MSCO.dll` auf den Keymaster laden. Spieler
|
||||||
spielen weiter zusammen, Server 2.8 müssen nicht aktualisiert werden.
|
mit derselben Netzwerk-Version spielen weiter zusammen, Server müssen nicht aktualisiert werden.
|
||||||
- **Großes Update** (Protokoll inkompatibel geändert): `ProtocolVersion` in `MSCO.cs` **und** `GameServer.ModVersion` im
|
- **Großes Update** (Protokoll inkompatibel geändert): `ProtocolVersion` in `MSCO.cs` **und** `GameServer.ModVersion` im
|
||||||
Server erhöhen (z.B. `2.9`), `ModVersion` auf `2.9.0`. Dann brauchen alle die neue Mod und den neuen Server.
|
Server erhöhen (z.B. `2.9`), `ModVersion` auf `2.9.0`. Dann brauchen alle die neue Mod und den neuen Server.
|
||||||
- Verglichen werden immer nur die ersten zwei Stellen; übers Netz geht nur die Netzwerk-Version.
|
- Verglichen werden immer nur die ersten zwei Stellen; übers Netz geht nur die Netzwerk-Version.
|
||||||
- **Automatisch hochladen**: Ist lokal `MSCO_RELEASE_TOKEN` gesetzt (= `RELEASE_TOKEN` des Keymasters, oder in
|
- **Automatisch hochladen**: Ist lokal `MSCO_RELEASE_TOKEN` gesetzt (= `RELEASE_TOKEN` des Keymasters, oder in
|
||||||
`%AppData%\MSCO
|
`%AppData%\MSCO\release-token.txt`), lädt jeder Release-Build eine neue Version selbst auf den Keymaster
|
||||||
elease-token.txt`), lädt jeder Release-Build eine neue Version selbst auf den Keymaster
|
|
||||||
(`release.ps1`, Changelog aus dem passenden Abschnitt in `CHANGELOG.md`). Gibt es die Version schon, passiert nichts.
|
(`release.ps1`, Changelog aus dem passenden Abschnitt in `CHANGELOG.md`). Gibt es die Version schon, passiert nichts.
|
||||||
|
|
||||||
## Aufbau
|
## Aufbau
|
||||||
|
|
||||||
| Datei | Aufgabe |
|
| Datei | Aufgabe |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `MSCO.cs` | Mod-Einstieg, Tastenbelegung |
|
| `Bootstrap.cs`, `MSCO.cs` | Start ohne MSCLoader (Doorstop), Versionen, Tastenbelegung |
|
||||||
| `MultiplayerManager.cs` | Sitzung, Nachrichten, Spielerliste, Spielstart, HUD |
|
| `MultiplayerManager.cs` | Sitzung, Nachrichten, Spielerliste, Spielstart, HUD |
|
||||||
| `NetSession.cs` | Netzwerk (TCP und Steam P2P), Protokoll |
|
| `NetSession.cs` | Netzwerk (TCP und Steam P2P), Protokoll |
|
||||||
| `LobbyUI.cs`, `Overlays.cs`, `UiTheme.cs` | Launcher, Konsole/Chat/Admin-Menü, gemeinsamer Stil |
|
| `LobbyUI.cs`, `Overlays.cs`, `UiTheme.cs` | Launcher, Konsole/Chat/Admin-Menü, gemeinsamer Stil |
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using System;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Harmony;
|
using Harmony;
|
||||||
using HutongGames.PlayMaker;
|
using HutongGames.PlayMaker;
|
||||||
using MSCLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using MSCLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using MSCLoader;
|
|
||||||
using Steamworks;
|
using Steamworks;
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using HutongGames.PlayMaker;
|
using HutongGames.PlayMaker;
|
||||||
using MSCLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using HutongGames.PlayMaker;
|
using HutongGames.PlayMaker;
|
||||||
using MSCLoader;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace MSCO
|
namespace MSCO
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,20 @@
|
|||||||
|
Third-party libraries shipped with MSCO
|
||||||
|
=======================================
|
||||||
|
|
||||||
|
0Harmony.dll - Harmony 1.2.0.1 by Andreas Pardeike
|
||||||
|
https://github.com/pardeike/Harmony - MIT License
|
||||||
|
Copyright (c) 2017 Andreas Pardeike
|
||||||
|
|
||||||
|
Newtonsoft.Json.dll - Json.NET 13.0.4 by James Newton-King
|
||||||
|
https://www.newtonsoft.com/json - MIT License
|
||||||
|
Copyright (c) 2007 James Newton-King
|
||||||
|
|
||||||
|
MIT License: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
||||||
|
associated documentation files (the "Software"), to deal in the Software without restriction, including without
|
||||||
|
limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||||
|
and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above
|
||||||
|
copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||||
|
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
|
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
Reference in New Issue
Block a user