# MSCO-Mods schreiben MSCO läuft ohne MSCLoader und hat eine eigene, kleine Mod-Schnittstelle. Eine MSCO-Mod ist eine .NET-3.5-DLL mit einer Klasse, die von `MSCO.MscoMod` erbt. MSCLoader-Mods laufen damit **nicht** (sie brauchen MSCLoader). ## Wo liegen Mods? | Ordner | | |---|---| | `\MSCO\Mods\*.dll` | eigene Mods – immer aktiv, werden beim Spielstart geladen | | `\MSCO\Mods\*.dll.off` | ausgeschaltet (Launcher → *Mods*) | | `\MSCO\Mods\Servers\*.dll` | Mods von Servern – nur aktiv, solange man auf einem Server ist, der sie verlangt | | Server: `data/mods/*.dll` | Mods, die der dedizierte Server an seine Spieler verteilt (Web-Panel → *Mods*) | Im Spiel: Seite **Mods** im MSCO-Menü, Konsole (F7) `mods`. Im Launcher: Seite **Mods** (hinzufügen, aus-/einschalten, entfernen). ## Server-Mods Liegen Mods in `data/mods` des Servers, bekommt jeder Spieler beim Beitreten die Liste (Name, Version, Größe, SHA-256). Fehlt ihm eine Mod, fragt das Spiel: **INSTALL & JOIN** lädt sie direkt vom Server (Prüfsumme wird kontrolliert), **CANCEL** verlässt den Server. Danach geht es ins Spiel. Hat der Spieler dieselbe Datei schon (gleiche Prüfsumme), wird nichts geladen. Server mit Mods bekommen in der Serverliste automatisch den Tag **MODDED**; im Server-Browser (Spiel, Launcher, Website) steht, welche Mods sie nutzen, und es gibt Filter *VANILLA* / *MODDED*. > Mods sind Programme und laufen mit vollen Rechten auf dem PC der Spieler. Serverbetreiber: nur Mods anbieten, denen ihr > vertraut. Spieler: nur auf Servern zustimmen, denen ihr vertraut. ## Mod veröffentlichen (Modliste auf msco.mbm.wtf/mods) Im MSCO Launcher unter **Mods → Hochladen**: DLL wählen (Name, Version und Beschreibung werden aus den Assembly-Attributen `AssemblyProduct`, `AssemblyInformationalVersion` und `AssemblyDescription` vorgeschlagen), eine **Mod-ID** vergeben (3–40 Zeichen, `a-z 0-9 _ . -`, z.B. `showboltsize`) und hochladen. Hochladen geht mit dem Launcher-Konto; eine Mod-ID gehört danach dir. Jede Version wird von einem MSCO-Admin geprüft (Admin-Bereich → *Mods von Spielern*) und ist erst danach öffentlich: auf und im Launcher unter **Mods → Durchsuchen** (ein Klick installiert, SHA-256 wird geprüft, Updates werden angezeigt). Eine neue Version braucht dieselbe Mod-ID und eine höhere Versionsnummer; bis sie freigegeben ist, bleibt die alte öffentlich. Den Status (wartet, öffentlich, abgelehnt mit Grund) siehst du unter **Meine Uploads**. Höchstens 10 MB pro Datei. > **Nicht verschlüsseln (obfuskieren)!** Verschlüsselte Mods (ConfuserEx, Dotfuscator, SmartAssembly …) lassen sich nicht > prüfen und werden bei der Prüfung abgelehnt. Der Keymaster erkennt bekannte Tools und zeigt das den Admins an. Beispiel mit Quellcode: [`examples/ShowBoltSize`](examples/ShowBoltSize) zeigt unter dem Fadenkreuz die Größe der Schraube, auf die man schaut. ## Eine Mod bauen Vorlage: [`examples/HelloMod`](examples/HelloMod) – Projekt (.NET Framework 3.5) mit Verweisen auf `UnityEngine.dll` (aus `mysummercar_Data\Managed`) und `MSCO.dll` (aus `\MSCO`, *Copy Local* aus). ``` msbuild examples/HelloMod/HelloMod.csproj -p:Configuration=Release -p:GamePath="C:\...\My Summer Car" ``` ```csharp using MSCO; using UnityEngine; public class HelloMod : MscoMod { public override string ID { get { return "hellomod"; } } // eindeutig: Buchstaben, Ziffern, . - _ public override string Name { get { return "Hello Mod"; } } public override string Version { get { return "1.0.0"; } } public override string Author { get { return "Ich"; } } public override void OnGameLoad() { Log("Im Spiel!"); } public override void Update() { if (Input.GetKeyDown(KeyCode.H)) Send(System.Text.Encoding.UTF8.GetBytes("wave")); } public override void OnMessage(int fromPlayerId, byte[] data) { string name; Log((Players.TryGetValue(fromPlayerId, out name) ? name : "?") + " winkt"); } } ``` Name und Version, die Launcher und Server-Panel anzeigen, kommen aus den Assembly-Attributen (`AssemblyProduct`, `AssemblyInformationalVersion`). ## Schnittstelle | Mitglied | | |---|---| | `ID`, `Name`, `Version`, `Author` | Angaben zur Mod (`ID` und `Name` müssen überschrieben werden) | | `OnLoad()` | einmal nach dem Laden | | `OnMenuLoad()`, `OnGameLoad()` | Hauptmenü bzw. Spiel (Szene `GAME`) geladen | | `Update()`, `FixedUpdate()`, `OnGUI()` | jeden Frame (wie bei Unity) | | `OnSessionStart()`, `OnSessionEnd()` | mit Server/Host verbunden bzw. getrennt | | `OnPlayerJoined(id, name)`, `OnPlayerLeft(id, name)` | Mitspieler kommt/geht | | `OnMessage(fromPlayerId, data)` | Daten, die dieselbe Mod (gleiche `ID`) bei einem anderen Spieler mit `Send` geschickt hat | | `Send(byte[] data)` | an dieselbe Mod bei allen anderen Spielern (bis 60 KB; P2P und dedizierter Server) | | `IsInSession`, `IsHost`, `LocalPlayerId`, `Players` | Sitzung, eigene ID, Spieler (ID → Name) | | `Log(text)`, `LogWarning(text)` | in die MSCO-Konsole (F7) und `output_log.txt` | Fehler in einer Mod fängt MSCO ab und schreibt sie ins Log. Wirft eine Mod ständig Fehler (50×), wird sie abgeschaltet. Harmony 1.2 (`0Harmony.dll`) liegt neben `MSCO.dll` und kann von Mods mitbenutzt werden.