Minecraft Clients: Das Mod Coder Pack: Unterschied zwischen den Versionen

Aus Jonas Notizen Webseite
Zur Navigation springen Zur Suche springen
(Von "Schnell zwischengespeicherte Sachen" (External SSD) kopiert)
 
K (→‎GuiScreen: Fixed table cell)
Zeile 778: Zeile 778:
 
<code>boolean isKeyComboCtrlC()</code>,<br>
 
<code>boolean isKeyComboCtrlC()</code>,<br>
 
<code>boolean isKeyComboCtrlV()</code>,<br>
 
<code>boolean isKeyComboCtrlV()</code>,<br>
<code>boolean isKeyComboCtrlA()</code> || Gibt <code>true</code> zurück, wenn [X/C/V/A] und [CTRL] gleichzeitig gedrückt werden, UND <code>isShiftKeyDown</code> sowie <code>isAltKeyDown</code> false zurückgeben.
+
<code>boolean isKeyComboCtrlA()</code>  
 +
| Gibt <code>true</code> zurück, wenn [X/C/V/A] und [CTRL] gleichzeitig gedrückt werden, UND <code>isShiftKeyDown</code> sowie <code>isAltKeyDown</code> false zurückgeben.
 
|-
 
|-
 
| ||  
 
| ||  

Version vom 26. August 2019, 11:13 Uhr

Inhaltsverzeichnis

Quellen

DISCLAIMER

Diese Anleitung/Diese Übersicht dient nur zur Veranschaulichung, was MCP ist, wie es funktioniert, wie man es aufsetzt und was man damit machen kann.
Bitte lest euch auch die unten aufgeführten Lizenzbedingungen von MCP, sowie die EULA (End User License Agreement, Lizenzbedingungen) von Mojang gut durch.
Ich trage keine Verantwortung für dass, was ihr mit diesem Wissen macht. (zB. Das erstellen und nutzen von Hack-Clients auf öffentlichen Servern ohne die explizite Erlaubnis, welche offensichtlich gegen Use MCP to create clients that are used for griefing or exploiting server bugs. verstoßen)

Die meisten Tutorials auf YouTube im Bezug auf MCP handeln zwar über Hack-Clients, und ich werde hier auch einige zwischen-durch verlinken, aber diese Tutorials sollte nur als "Solche Möglichkeiten stehen dir zur Verfügung/So machst du etwas." angesehen werden. (zB. implementation eines Modul/Eventhook-Systems, oder wie man mit dem Player/der Welt/den Kreaturen Sachen anstellen kann, welche Funktionen es gibt, das GUIScreen-System, etc...).


Was ist MCP?

Das Mod Coder Pack (ehemals Minecraft Coder Pack) ist eine Sammlung von Scripten und Tools, die Entwicklern helfen, Modifikationen für Minecraft zu erstellen. [1]

Das Minecraft Coder Pack hilft Modentwicklern, Minecraft-Java-Klassen zu dekompilieren, zu ändern und anschließend wieder zu kompilieren. Das Paket enthält Skripte zum Dekompilieren von Spiel und Server. [2]



Lizenz und Nutzungsbedingungen

Lizenzbedingungen der aktuellen MCP940 (Minecraft 1.12), gefunden in der Datei /docs/README-MCP.TXT im gewünschten MCP-Ordner. (Links und Wikimedia-Syntax hinzugefügt von mir):

MCP - Mod Coder Pack
MCP is (c) Copyright by the MCP Team

License and terms of use.

No warranties. If MCP does not work for you, or causes any damage, it's your problem. Use it at own risk.

You are allowed to:
* Use MCP to decompile the Minecraft client and server jar files.
* Use the decompiled source code to create mods for Minecraft.
* Recompile modified versions of Minecraft.
* Reobfuscate the classes of your mod for Minecraft.

You are NOT allowed to:
* Use MCP to do anything that violated Mojangs terms of use for Minecraft.
** (Siehe https://account.mojang.com/documents/minecraft_eula)
* Release Minecraft versions or modifications that allow you to play without having bought Minecraft from Mojang.
* Release modified or unmodified versions of MCP anywhere.
* Use any of MCPs scripts, tools or data files without explicit written permission.
* Make money with anything based on MCP (excluding Minecraft mods created by using MCP).
* Use MCP to create clients that are used for griefing or exploiting server bugs.
* Release the decompiled source code of Minecraft in any way.





Mitwirkende

Quellen

Twitter-Post von SeargeDP - 2015

Hier ein Austrag der MCP940 (1.12.2) und (1.2.5), übersetzt auf Deutsch mit einigen zusätzlichen Links:

Kern-Team

Searge - (Gamepedia-Eintrag, Twitter)
* Gründer vom MCP-Projekt
* Behebt alle Kompilierungsfehler im dekompilierten Quellcode
* Erstellte das MCP-Mod-System und dessen API
* Erstellte den Eclipse-Arbeitsbereich für MCP 4.x
* Erstellte "RetroGuard", das Deobfuskations-Modul für MCP 3.0
* Erstellte das neue Mod-System
* Seit 2014 offizielles Mitglied bei Mojang [3]
ProfMobius - (Gamepedia-Eintrag, Twitter)
* Ersteller der Umbennenung von obfusktierten Code-Identifier (wie Klassen/Methoden/Feld-Namen) des Client/Server-Codes (Siehe MCP-Bot)
* Ersteller neuer Prozederen zur erneuten-Verschleierung (Re-Obfuskation) des Codes
* Half bei der Portierungen von Skripten nach GNU/Linux
* Entwickler und Betreuer des MCP-Bots
** Extra: MCPBot ist ein von der Community gesteuertes Projekt in Form eines IRC-Bots, mit dem Mitwirkende aussagekräftige Namen und Beschreibungen für Felder, Methoden und Methodenparameter im Java-Code angeben können, der mit dem Mod Coder Pack (MCP) erstellt wurde.
** Extra: Eine veraltete Kalkulationstabelle, die für das "Deobfuscation-Mapping" (die Namenszuordnung) genutzt wurde, findet man hier.
* Ist jetzt kahl, nachdem er zu viel mit Java-Pool und erneuter Verschleierung gearbeitet hat ;)
* Erstellt die neuen Workflow-Skripts und Namenszuordnungen für MCP 3.0
IngisKahn - (Twitter)
* Ersteller des Bytecode-Vergleichstools, mit dem die Namenszuordnungen (des MCP-Bot) für neue Minecraft-Versionen schnell aktualisiert/eingefügt werden können
* Trägt zur Deobfuskations-Tabelle des MCP-Bot bei
* Arbeitet hart an der Erstellung besserer, interner Tools zum Mappen von Updates und dessen Dekompilieren
Fesh0r - (Twitter)
* PHP/SQL Code-Affe
* Verwendet seine Magie, um Zuordnungen, Patches und allgemeine Veröffentlichungsarbeiten zu erstellen
* Hat Searge's offizielle Genehmigung, MCP-Veröffentlichungen zu erstellen ;)
* Stellt sicher, dass das Team die richtigen Patches für den von JAD generierten Quellcode erhalten
* Verwaltet Skripte und Toolkits
* Optimiesierte den Retroguard- und Exceptor-Tools 
R4WK - (Twitter)
* Arbeitet an MCP-Updates und trägt zum neuen Mod-System bei
* Unterstützt ZeuX bei seinem "Techne" Model-Editor
ZeuX
* Hilft in den IRC-Kanälen - Leiter der Personalabteilung
* Erledigt die Server-Patches für die aktuellsten Versionen - Wenn man auf (Patch-bezogene) Probleme stößt, liegt es an ihm :P
* Ersteller des berühmten "Techne" Model-Editors für Minecraft
* Fügt Funktionen zum neuen Mod-System hinzu
bspkrs - (Twitter, Webseite)
* Erstellte die neue Mapping-Datenbank und hat am neuen MCPBot-"Reborn" gearbeitet
* Erstellte das neue MCP-Mapping-Viewer-Tool
* Arbeitete an der Aktualisierung zu Minecraft 1.8 und 1.8.8
LexManos - (Twitter)
* Half Fesh0r, MCP für Minecraft 1.0.0 / 1.0.1 zu aktualisieren
* Half bei der Aktualisierung der Skripte und Zuordnungen für die neuen, von Minecraft 1.6.x eingeführten Strukturen.
* Hat die meiste Arbeit für das Update auf Minecraft 1.7.10, 1.8.8, 1.8.9, 1.9, 1.10, 1.11.x und 1.12 ausgeführt
* Ersteller von Forge (Gamepedia-Eintrag), der un-offiziellen und weitest verbeiteten Modding-API
CPW - (Twitter)
* Half bei der Aktualisierung der Skripte und Zuordnungen für die neuen, von Minecraft 1.6.x eingeführten Strukturen.
* Hat eine Menge Arbeit geleistet, um ein Update auf Minecraft 1.7.10, 1.8.8, 1.8.9, 1.9, 1.10, 1.11.x und 1.12 durchzuführen

Weitere

Stiver
* Erlaubte dem Team, sein fernflower-Decompiler in MCP zu benutzen 
** Extra: (Siehe Notiz von Stiver an Searge selbst und zu den Lizenzbedingungen unter /docs/README-FF.txt im gewünschten MCP-Ordner.)
303
* Wiki-Mitwirkender
* Versucht, Neulingen in den IRC-Kanälen zu helfen
* Stellt sicher, dass Modloader-Mods mit MCP erstellt werden können
Mr_okushama - (Twitter?)
* Wiki-Mitwirkender
* Öffentlicher Support Manager
* IRC-Operator
* Erlöser der Aprilscherze 2011
Cryect
* Trägt viel zur Deobfuscation-Mappings-Tabelle (vom MCP-Bot) bei
* Ersteller des fantastischen AdventureCraft Mod
Mysterio N - (MinecraftForum.net-Account?)
* Erstellte das getmodsource-Skript
Generic
* Verbessert das Bytecode-Vergleichstool von IngisKahn
* Einige wichtige Funktionen zum Retroguard hinzugefügt
Risugami
* Der Typ, der die ersten Mods entwickelte, die ich (Searge) jemals in Minecraft verwendet habe
* Der Ersteller des Modloader, der uns die Erlaubnis erteilt hat, Dateien aus seinem System in MCP aufzunehmen
fotoply
* Half bei der Verbesserung der Batch-Dateien
Cadde
* Community-Manager und Wiki-Manager
* Hilft bei der De-Obfuskationstabelle mit
* Mod-Support (Lässt alte Mods mit MCP wieder funktionieren)
* Allround Handwerker
Vaprtek
* Hilft bei der De-Obfuskationstabelle mit
* Kann Haustierkriechpflanzen herstellen
gronk
* Script-Supporter
n00bish
* Linux-Skriptpfleger
Sage Pourpre MinecraftForum.net-Account
* Sein Thread[4] in den Foren hat mich (Searge) dazu inspiriert, dieses Toolpack zu erstellen
Tei
* Unterstützt das MCP-Projekt seit der Veröffentlichung der ersten Version
spec10
* Der neue Linux-Script-Typ
Head
* Wiki-Mitwirkender / Administrator
* Erklärt die Klassen und dessen Felder im Wiki
MissLil
* Verschiedene Scripting-Sachen
* Viele Reverse Engineering
* Macht Anmerkungen zu OpenGL-Konstanten
ScottyDoesKnow
* obfuscathonCharmer, die grafische Benutzeroberfläche von obfuscathon
Chase
* MCP Launcher Work
* Externes Glas laden
* Scrollbare Modliste.
titegtnodI
* Wiki-Mitwirkender
* IRC-Operator
UltraMoogleMan
Yamachi

... und eine große Community

  • welche bei der Namenszuordnungstabelle vom MCBot (und früher Google-Spreadsheets) mitgearbeitet hat
  • welche sich für MCP einsetzten, Mods damit erstellen und anderen dabei Helfen <3






Aufbau vom MCP-Ordner

bin

Notiz, gefunden in /docs/README-MCP.TXT:

To add new resources to the game, for example png files, put them in the bin folder tree, they will also get copied to the reob folder
automatically when you reobfuscate your changes.

(Dieser Ordner existiert erst nachdem decompile.bat/sh aufgerufen wurde.)

conf + Notiz

Enthält alle (vom MCP-Bot generierten) Tabellen zur Umbenennung der von Fernflower de-obfuskierten Quellcode-Literalen in ihren eigentlichen Namen.

  • Siehe MCBot - Exports für die neuesten Zuordnungen - täglich aktualisiert

Quote von Pokechu22 "Setting up MCP without a full MCP release.md":

The SRG file is what converts obfuscated names into an intermediate step where names are (mostly) the same between versions; 
The mappings files convert those intermediate names into the names you see and are used to.

docs

Hier befinden sich

  • Anmerkungen/Lizenzen des fernflower-decompiler von Stiver (Siehe /docs/README-FF.txt und /docs/fernflower)
  • Der Sourcecode des retroguard-deobuskator von Searge (Siehe /docs/source/retroguard.zip)
  • Die Apache 2.0 Lizenz für den Bugfinder "FindBugs JSR305" (Siehe /docs/APACHE-LICENSE-2.0.txt)
  • Anmerkungen zur benutzung mit der Eclipse-IDE (Siehe /docs/APACHE-ECLIPSE.txt)
  • Anmerkungen zur benutzung unter Linux/OSC (Siehe /docs/README-Linux und /docs/README-OSC)

+ Alle Informationen zu...

  • den Lizenzbedingungen
  • den Vorraussetzungen
  • einem HOW-TO
  • wichtige Notizen zu diversen Theme
  • eine Liste aller Mitwirkenden

...des MCP-Projekts (Siehe /docs/README-MCP.TXT).

eclipse

Vorgefertigter Eclipse-Workspace

jars

Der ".minecraft-Ordner" des Projekts.

Um eigene Bilder/Resourcen in seinen Client einzufügen, gibt es den Ordner /bin (Siehe oben).

lib

???
(Dieser Ordner existiert erst nachdem decompile.bat/sh aufgerufen wurde.

logs

Log-Dateien der Skripte.

  • /logs/client_compile.log: Hier sollten nur "DEPRECATED" warnungen auftauchen
  • /logs/client_exc.log: LOG-Datei des MJInjectors
  • /logs/mcp.log: Sehr Explizite/Ausführliche LOG-Datei des dekompilierungsprozesses vom Programm decompile.bat/sh.
  • /logs/mcperr.log: Ausschnitt der Fehlermeldungen der obrigen mcp.log-Datei.

mappingviewer

Siehe MinecraftForum.net-Thread des MCPMappingViewers

MCP Mapping Viewer is a Java GUI application that allows you to easily navigate through the MCP obfuscation data used during the decompilation process.

runtime

Enthält alle eigentlichen, in Python geschriebene Skripte/Tools und dessen benötigten Python/Java-Dependencies.

Alle .bat und .sh-Skripte im Hauptverzeichniss vom MCP-Ordner führen eigentlich nur diese Skripte aus.
Beispiel aus decompile.bat und decompile.sh:

@echo off
runtime\bin\python\python_mcp runtime\decompile.py %*
pause
#!/bin/bash
./runtime/decompile.py "$@"

src

Der eigentliche, deobfuskierte Sourcecode mit dem man arbeitet befindet sich in diesem Ordner.

  • Im eclipse-Ordner befinden sich nur Einstellungen der Entwicklungsumgebung. Unter anderem verweist die Einstellung "Content Root" auf diesen Ordner.

(Dieser Ordner existiert erst nachdem decompile.bat/sh aufgerufen wurde.

temp

???
(Dieser Ordner existiert erst nachdem decompile.bat/sh aufgerufen wurde.

CHANGELOG

Changelog der verschiedenen MCP-Versionen, auch gefunden unter /docs/README-MCP.TXT.

LICENSE.txt

Lizenzbedingungen von MCP, auch gefunden unter /docs/README-MCP.TXT.







Eigenen Minecraft-Client erstellen

MCP und IntelliJ-Umgebung aufsetzen

Quelle: Setting up the MCP Workspace

Voraussetzungen

Anleitung/Anmerkungen der /docs/README-MCP.TXT, auf Deutsch übersetzt:

  1. Java SDK Standard Edition [5]
  2. Pfad zum Java JDK/JRE-bin-Ordner zur PATH-Variable hinzufügen [6] (Damit alle JDK-Befehlszeilenprogramme wie javac verfügbar sind)
    1. Notiz: MCP 9.x+ sollte auch mit Java 8 funktionieren
  3. Die gewünschte Minecraft-Version muss bereits auf dem System unter %APPDATA%/.minecraft/versions/... auffindbar sein (aka. schoneinmal gestartet worden sein).
    1. Ansonsten kommt beim dekompilieren folgende Fehlermeldung:
Json file not found in C:\Users\DEINBENUTZER\AppData\Roaming\.minecraft\versions\1.7.10\1.7.10.json
Please run launcher & Minecraft at least once.

Wenn alle obrigen Vorraussetzungen erfüllt sind (Entsprechende Minecraft- und Java-Version installiert), kann man nun seine gewünschte MCP-Version herunterladen und an seinen gewünschten Workspace-Ort entpacken.

MCP herunterladen

Im Englischen Minecraft-Gamepedia-Eintrag findet man so ziemlich alle MCP-Versionen. (Sogar bis zur aller-ersten).

Auf der Offizielle ModCoderPack-Seite findet man die Download-Links zu den wichtigsten, finalen MCP-Versionen ab der Version 1.7.10. Darunter: (Stand April 2019, kopiert von der oben genannten offiziellen Seite)

Download Beschreibung
mcp940.zip Minecraft client 1.12 & server 1.12
mcp937.zip Minecraft client 1.11.2 & server 1.11.2
mcp931.zip Minecraft client 1.10 & server 1.10
mcp928.zip Minecraft client 1.9.4 & server 1.9.4
mcp918.zip Minecraft client 1.8.8 & server 1.8.8
mcp908.zip Minecraft client 1.7.10 & server 1.7.10

MCP auf Updates überprüfen

Als erstens sollte man mit dem Skript updatemcp.bat/sh checken, ob irgend ein neuer Patch seiner MCP-Version verfügbar ist und diesen dann mit einem "Yes" automatisch installieren.

== MCP 9.40 (data: 9.40, client: 1.12, server: 1.12) ==
"scalac" is not found on the PATH.  Scala files will not be recompiled
== Updating MCP ==
No new updates found.
Drücken Sie eine beliebige Taste . . .

IntelliJ vorbereiten

  • IntelliJ starten
  • [File] (Oben links) -> [Settings] (Strg+Alt+S)
  • [ Appearance & Behavior] (Linke Seite) -> [ Path Variables] (Ganz unten)
  • [+]
    • Name: "MCP_LOC"
    • Value: "[Vollständiger-Pfad zum Hauptverzeichniss deines MCP-Ordners]"
    • -> [OK]
  • [APPLY] -> [OK] (Unten Rechts)

Dekompilieren

Das Skript decompile.bat/sh sorgt jetzt für die eigentliche Magie von MCP:
Sie holt sich die obfuskierte Minecraft-Version aus dem %APPDATA%/.minecraft/versions/-Ordner, wandelt alle obfuskierte Klassen/Feld/Methoden-Namen wie "aab$" in den eigentlichen Namen um, kopiert alle Assets (etc), kümmert sich um alle Dependencies&Fehler und erstellt uns einen Eclipse-Arbeitsplatz.

  • Die Fehlermeldung !! Missing server jar file. Aborting !! kann man ignorieren, weil uns hier nur der Client interessiert.
    • Wenn man doch auch an der modifierung des Servers interessiert ist, muss man sich eine reine (keine mods) Version der der minecraft_server.jar herunterladen, und in den /libs-Ordner von MCP packen.
  • Die Fehlermeldung "scalac" is not found on the PATH. Scala files will not be recompiled kann man mit Style ignorieren, weil wir nicht mit Scala programmieren werden, sondern mit Java.
    • Diese Fehlermeldung kommt, weil ich kein Scala-SDK auf meinem Computer installiert habe

Quote von Gamepedia - Setting up the MCP workspace:

"updatemcp" updates any MCP files that can be updated. This is very important to run, as it could fix major bugs. 
"decompile" decompiles the Minecraft JAR and minecraft_server.jar. This allows you to see the source code of Minecraft and mod it. 
Note that while decompiling, some warnings or errors may appear. 
* An example of a warning that may appear includes "Modified jar detected! Unpredictable results!!" This warning should appear, as ModLoader is installed. Do not worry about this. 
* An error that may occur includes "1 out of 1 hunks failed". This error also should appear, and will not damage any files or do anything to disrupt the decompiling process.


Beispiel-Ausgabe des dekompilierungsprozesses:

== MCP 9.40 (data: 9.40, client: 1.12, server: 1.12) ==
"scalac" is not found on the PATH.  Scala files will not be recompiled
# found ff, ff patches, srgs, name csvs, doc csvs, param csvs, astyle, astyle config, rg, ss
Looking in C:\Users\Pixel\AppData\Roaming\.minecraft\versions for mc installs... OK
Copying assets... OK
Parsing JSON file... OK
Looking for minecraft main jar... Not found
Copying minecraft main jar... OK
> Checking libraries...
        Copying library jinput... OK
        Copying library icu4j-core-mojang... OK
        Copying library httpcore... OK
        Copying library log4j-api... OK
        Copying library commons-lang3... OK
        Copying library jna... OK
        Copying library lwjgl-platform-natives-windows... OK
        Copying library libraryjavasound... OK
        Copying library jopt-simple... OK
        Copying library text2speech... OK
        Copying library guava... OK
        Copying library oshi-core... OK
        Copying library httpclient... OK
        Copying library commons-compress... OK
        Copying library text2speech-natives-windows... OK
        Copying library fastutil... OK
        Copying library platform... OK
        Copying library codecjorbis... OK
        Copying library soundsystem... OK
        Copying library librarylwjglopenal... OK
        Copying library lwjgl_util... OK
        Copying library commons-codec... OK
        Copying library jutils... OK
        Copying library patchy... OK
        Copying library commons-logging... OK
        Copying library lwjgl... OK
        Copying library commons-io... OK
        Copying library realms... OK
        Copying library authlib... OK
        Copying library gson... OK
        Copying library jinput-platform-natives-windows... OK
        Copying library codecwav... OK
        Copying library log4j-core... OK
        Copying library netty-all... OK
> Checking Natives...
        Extracting native lwjgl.dll... OK
        Extracting native OpenAL32.dll... OK
        Extracting native jinput-dx8_64.dll... OK
        Extracting native SAPIWrapper_x86.dll... OK
        Extracting native jinput-wintab.dll... OK
        Extracting native jinput-dx8.dll... OK
        Extracting native jinput-raw.dll... OK
        Extracting native OpenAL64.dll... OK
        Extracting native SAPIWrapper_x64.dll... OK
        Extracting native jinput-raw_64.dll... OK
        Extracting native lwjgl64.dll... OK
> Copying jsr305-3.0.1.jar to Libraries
> Copying jsr305-3.0.1-sources.jar to Libraries
== Decompiling client using fernflower ==
> Creating SRGs
> Applying SpecialSource
> Applying MCInjector
> Creating renamed srg
> Filtering classes
> Decompiling
> Unpacking jar
> Copying sources
> Generating package-info files
> Applying fernflower fixes
> Applying patches
> Cleaning comments
- Done in 150.44 seconds
== Reformating client ==
> Cleaning sources
> Replacing OpenGL constants
> Reformating sources
- Done in 21.71 seconds
== Updating client ==
> Adding javadoc
> Renaming sources
- Done in 28.11 seconds
!! Missing server jar file. Aborting !!
== Recompiling client ==
> Cleaning bin
> Recompiling
- Done in 28.29 seconds
> Generating client md5s
Drücken Sie eine beliebige Taste . . .


Client starten

Jetzt kann man seine neue, dekompilierte Version von Minecraft einmal mit dem Skript startclient.bat/sh starten, um zu schauen ob alles funktioniert hat.

IntelliJ Arbeitsplatz-Umgebung aufsetzen

IntelliJ's Hauptmenü öffnen

  1. [Import Project]
    1. "eclipse"-Ordner deines MCP-Client-Ordners auswählen -> [OK]
    2. [Import project from external model] anhaken und [Eclipse] auswählen -> [Next]
    3. Falls ein Fenster mit "Select Eclipse Projects directory" kommt, alles auf Standard lassen -> [Next]
    4. Kontrollkästchen vom [Server] entfernen -> [Next]
    5. Falls ein Fenster mit "Choose project code style" kommt, "Use default project style" auswählen -> [Next]
    6. Favorisierte Project-SDK wählen, in meinem Fall 1.8. (mindestens 1.6) -> [Finish]
    7. Warn-Meldung "Imported project refers to unknown jdks JavaSE-1.6" taucht auf, weil Minecraft JDK-1.6 nutzt, und wir (hoffentlich) eine andere JDK Version installiert haben -> [OK]
  2. [File (oben links) -> Project Structure] (oder STRG+ALT+SHIFT+S)
    1. Sidebar/Tab [Project] anklicken
      1. Unter [Project name:] sollte man seinem IntelliJ-Projekt einen Namen geben, weil sonst alle deine Clients in der Übersicht als "eclipse" angezeigt werden
      2. Unter [Project SDK:] muss man seine gewünschte Java-SDK für das Projekt auswählen
    2. Sidebar/Tab [Modules] anklicken -> [Client]-Module (links) auswählen
      1. Unter dem Tab [Dependencies] die [Module-SDK] auf die von vorhin gewählte Java-SDK-Version ändern
      2. Falls unter dem Tab [Dependencies] alle Bibliotheken rot-unterstrichen sind, liegt es höchstwarscheinlich daran dass man die Schritte vom Kapitel "IntelliJ vorbereiten" nicht befolgt hat.
      3. Unter dem Tab [Sources] sollte Rechts (unter "+ Add Content Root") 2 Pfade seines MCP-Ordners beschrieben sein: \eclipse\Client und \src\minecraft. (Wenn nicht, diese in der gleiche reihenfolge hinzufügen)
      4. Unter dem Tab [Sources] die [Language-Level] auf die von vorhin gewählte Java-SDK-Version ändern
  3. Oben rechts, neben den "Compile-Symbol" (bei mir ein Hammer) auf die Dropdown-Liste klicken -> [Edit Configurations]
    1. [+ (oben links) -> Application]
      1. ggf. seinen neuen erstellen Starter unter Name umbenennen.
      2. Main class: "Start" (Wird rot markiert, passt aber)
      3. VM options: "-Djava.library.path=versions/DEINE_VERSION/DEINE_VERSION-natives" (Client-Version einfüllen)
      4. Working directory von ...\eclipse auf ...\jars umändern.

Nun sollte man seinen Client wie jedes andere normale Java-Projekt ganz einfach mit IntelliJ starten können.

Optifine in seinen Client integrieren

Optifine-Sourcecode mit der gewünschten Version von hier herunterladen.

Alles aus dem gerade heruntergeladenem .zip-Archiv in den Ordner /src/minecraft/-Ordner seines MCP-Clients entpacken (und somit auch vorhandenes (wie zB. den net und mcp-Ordner) mit den Optifine-Versionen überschreiben/ersetzen).

Fertig

Client exportieren

Um seinen MCP-Client jetzt auch im originalen Launcher benutzen zu können, so dass man es auch anderen weiter-reichen kann und nicht immer Intellij braucht, muss man es in eine .jar-Datei exportieren.

Auschnitt aus Gamepedia - .minecraft - Versionsordner

In dem Versionsordner hat jede Minecraft-Version, die man über den Launcher spielen möchte, einen eigenen Ordner, der die Versionsnummer trägt.
In jedem Versionsordner steht eine minecraft.jar-Datei, die das ausführbare Java-Programm und einen Teil der Standard-Ressourcen enthält. 
Die Datei heißt nicht wirklich minecraft.jar, sondern trägt immer die jeweilige Versionsnummer als Namen, also z.B. 1.7.4.jar.

Gestartet wird das Programm über den Launcher, der das entsprechende Java-Kommando zusammenstellt. 
Die dazu notwendigen Informationen (Pfade der Programmbibliotheken und weitere Parameter) holt sich der Launcher aus der json-Datei, die auch im Versionsordner steht (zum Inhalt der jar-Datei siehe minecraft.jar).
Beim Start einer Version erzeugt der Launcher im Versionsordner zwei Unterordner, die beim Beenden der Version wieder gelöscht werden:
* logs: enthält immer die aktuelle Protokolldatei latest.log. Sie wird beim Beenden der Version nach .minecraft/logs verschoben.
* Der zweite temporäre Unterordner trägt die Versionsnummer und die Bezeichnung natives im Namen, gefolgt von einer ID, die bei jedem Start wechselt. Er enthält betriebssystemabhängige Bibliotheken, die der Launcher zusammengestellt hat und die das Programm benötigt.


SCHRITT 1 - Client als .jar exportieren
Bis jetzt haben wir unseren Klienten immer nur mit IntelliJ's-Starter-Funktion "vom Sourcecoude-auf" gestartet.
Um aus dem Sourcecode jetzt eine ".jar-Archivdatei" zu erstellen, bietet uns IntelliJ eine sehr nette Funktion, die man wie folgt erreichen/aufsetzen kann:

  1. [File -> Project Structure] (STRG+ALT+SHIFT+S) -> Tab [Artifacts] öffnen
  2. [+ -> JAR -> From Modules with dependencies]
    1. Module: Client
    2. Main Class: Start
    3. Extract to the target jar
    4. [OK]
  3. Unter [Output Directory] ggf. den Pfad ändern, wo man die .jar exportiert haben möchte.
  4. Alle "Extracted Libraries" von Links markieren und mit [-] entfernen, so dass links nurnoch mehr DEINPROJECT.jar> 'DEINPROJEKT' compile output und realms-x.xx.xx.jar stehen

Nun kann man mit

  1. [Build (oben) -> Build artifacts -> DEIN_CLIENT -> Build]

seine .jar-Archivdatei am angebenen Ort erzeugen lassen.


TODO nächste Schritte
SCHRITT 2 - Manifest entfernen


SCHRITT 3 - Versionsordner erstellen


SCHRITT 4 - SPIELEN!


Troubleshooting

kein Sound

Problem: In Minecraft kommt kein Sound und in die Konsole wird beim starten mit lauter Missing sound for event: minecraft:....-Fehlermeldungen vollgespammt.

Lösung: In der Klasse net.minecraft.Start ist ein falscher assetIndex eingetragen.

  • Einfach die Zeile mit Main.main(....) finden und "--assetIndex", "1.8", mit "--assetIndex", "DEINE_VERSION", ersetzen.

Normalerweise sollte dies MCP automatisch beim dekompilieren mithilfe der Datei /conf/versions.cfg machen, aber es gibt anscheinend ein paar Patches indem dies nicht funktioniert, wie es zB. bei meiner MCP940 der Fall war.

Aufbau von MCP

EINFÜHRUNGS-NOTIZ - Unendlich Möglichkeiten

Jetzt, wo wir eine laufende MCP-Minecraft-Instanz am laufen haben, dessen Sourcecode aus richtigen Namen besteht und wir "frei" editieren können, können wir alles machen was wir wollen. Der einzigste, der uns ab hier bremsen noch kann, sind unsere unsere Kentnisse über den Minecraft-Sourcecode und unsere Java-Kentnisse. (oder die Lizenzbedingungen, wenn wir "cheats" kommerziell/auf Servern betreiben wollen. :D)


Als aller erstens muss man sich erst-einmals einen überblick über Minecrafts-Sourcecode beschaffen, also wo was wie aufgerufen/gehandhabt wird, ...

  • TIPP: Wenn man einen gewissen Sourcecode-Text hat (zB. aus einem Konsolen-Output) kann man dessen Herkunft mit IntelliJ's Tastenkombination [STRG+SHIFT+F] suchen, und sich mal den Code rundum anschauen und versuchen zu verstehen was abgeht.
  • WICHTIGER HINWEISS: Uns interessiert nur der net.minecraft-Ordner. Alle anderen Ordner, wie zB. net.minecraftforge, shadersmod, javax.math nicht anfassen!

Da der Minecraft-Sourcecode rießig groß ist, werde ich hier natürlich NIE auf jede Variable/Klasse/Methode/... eingehen können, deswegen:

  • Dank MCP haben die meisten, für uns interesannten Objekte einen sinnvollen Namen bekommen. Ich würde JEDEM raten, einfach mall durch ein paar Klassen zu scrollen und zu schauen wofür die Klasse ist, was man mit der Klasse machen kann, wie ich vllt. reinpfuschen/was verändern kann und somit weiß wie es funktioniert. Stichwort: "Reverse Engineering" (Das finde ich sooo cooool an MCP <3)

Mit welchem Programmier-Paradigma/Aufbau ihr eure Client-Funktionen in Minecraft's-Sourcecode einbindet/handhabt, ist natürlich wie bei jedem Programmier-Projekt komplett eurer Imagination überlassen! ;)


Ich hoffe ich verstoße mit meinen Einblicken/Übersichten über das Spiel/dessen Sourcecoude nicht gegen "Release the decompiled source code of Minecraft in any way.", und dass ich genug DISCLAIMER gegegben hab :D.

Interesannte Links

Auf wiki.vg findet man alle technischen Spezifikationen zu den verschiedenen Protokoll-Spezifikationen von Minecraft, Mojang/Realms/...-Schnittstellen, Tools & Mods sowie Informationen zu anderen Minecraft-Formaten uvm.

Wie alles beginnt

Gestartet wird Minecraft mithilfe der Methode net.minecraft.client.main.Main#main(String[] args).

  • In IntelliJ haben wir die Klasse Start als Eingangspunkt eingetragen, welche die obrige Methode mit "Dummy-MCP-Daten" aufruft. Beispiel-Auschnitt aus MCP940:
new String[] {"--version", "mcp", "--accessToken", "0", "--assetsDir", "assets", "--assetIndex", "1.12", "--userProperties", "{}"}
  • Im Versionsordner sind diese Daten in der .json-Datei vermerkt:
{
        ...
        "mainClass": "net.minecraft.client.main.Main", 
        "minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userType ${user_type} --versionType ${version_type}"
        ...
}

Ich bin zwar kein MCP-Dev, aber wenn man ein bisschen "Code lesen" kann, sollte man eigentlich bei so gut wie jeder Klasse den dreh rauskriegen:

  • Es werden alle Start-Argumente übernommen, und mithilfe eines OptionParsers in ein OptionSet-Objekt verwandelt
    • Falls eine Proxy (proxyHost, proxyUser und proxyPass) angegeben wurde, wird diese als java.net.Proxy-Objekt initiiert
    • Falls ein Benutzer angegeben (username, uuid, accessToken und userType) wurde, wird dieser als net.minecraft.util.Session Objekt initiiert.
      • Falls kein Benutzername angegeben wurde, erhält man den Namen "PlayerXXX" wobei "XXX" eine zufällige generierte Zahl (0 bis 1000) darstellt, berechnet mithilfe der derzeitigen Systemzeit
      • Falls keine UUID angegeben wurde, wird diese auf den Benutzername gesetzt (= ungültig)
      • Falls kein Benutzer-Typ angegeben wird, wird mit dem Typ "legacy" gerechnet. (Zur Auswahl stehen: "legacy" und "mojang", siehe net.minecraft.util.Session$Type)
      • Der AccessToken muss angegeben werden, MCP übergibt diesen in der Klasse Start mit dem Wert "0". (= ungültig)
    • -> Fast jeder möglichen Optionen wurde bis jetzt ein Standardwert zugewiesen. Aus dieser Ansammlung von Optionen wird jetzt ein eigenes net.minecraft.client.main.GameConfiguration-Objekt erstellt.
      • Dieses Objekt ist einfach nur eine Container-Klasse mit allen möglichen Eigenschaften, sortiert in Unter-Klassen (wie GameConfiguration.UserInformation), indem jede Option als Variable für "den nächsten in der Boot-Reihe" einfach zur Verfügung gestellt wird
    • Der Haupt-Thread kriegt seinen Namen und Java's Runtime eine Shutdown-Hook
  • Danach wird die (einzigste) Instanz der Minecraft-Klasse erstellt (welche zudem die GameConfiguration als Parameter überbekommt), die jetzt die weiteren Schritte einleitet
    • Die Klasse Minecraft besitzt so ziemlich alle Variablen, die die GameConfiguration eigentlich auch besitzt.
    • Die Methode net.minecraft.init.Bootstrap#register() initiiert das registrieren aller Blöcke, Items, Stats, Biome, etc...
  • Nachdem alle Start-Konfigurationen ausgehandelt wurden, und die wichtigsten Sachen anfänglich registriert wurden, wird jetzt die Methode net.minecraft.client.Minecraft#run() aufgerufen
    • (Ab hier wird jeder Fehler in Minecraft's CrashReport-Style aufgefangen und bearbeitet, bevor das Spiel einfach schließt. (Bemerkbar an der "#@!@# Game crashed! Crash report saved to: #@!@#"-Nachricht) )
    • Als erstens wird die, auch für uns interessante, net.minecraft.client.Minecraft#init()-Methode aufgerufen. (MCP-Kommentar: Starts the game: initializes the canvas, the title, the settings, etcetera.)
      • Alle Spieleinstellungen werden aus dem Daten-Verzeichnis (net.minecraft.client.Minecraft#mcDataDir) geladen
      • Die Nachricht "LWJGL Version: {}" wird ausgegeben, das Fenster und alles rund-drum wird erstellt
      • Alle anderen Manager, (speziell die für die rendern/texturen-Aufgaben) welche in der Minecraft-Klasse als Variable erreichbar sind, werden instantiiert. (Darunter auch die renderEngine sowie der fontRenderer)
      • Das GuiMainMenu wird angezeigt. Das Spiel wurde erfolgreich gestartet.
    • Wenn alles gut gelaufen ist, geht Minecraft in die dauerschleife. (Siehe net.minecraft.client.Minecraft#runGameLoop)

Wichtige und Interessante Klassen

Die Minecraft-Klasse ist einer der Anfangs interesanntesten Klassen, auf die man mal einen Blick werfen sollte.
Hier einmal eine Liste der wichtigsten Variablen der Minecraft-Klasse, mit dessen dazugehörigen Verwendungszweck:

Packet Variable Beschreibung
org.apache.logging.log4j Logger LOGGER Minecraft's Log4J-Instanz
net.minecraft.client.multiplayer PlayerControllerMP playerController
int displayWidth und int displayHeight eigentliche Größe des Bildschirms in Pixel. Fürs rendern sollte man die Werte der Klasse net.minecraft.client.gui.ScaledResolution verwenden.
net.minecraft.client.multiplayer WorldClient world Welt, in welcher sich der Spieler sich gerade befindet (null wenn wir in keiner Welt sind, sondern nur eine GUI "am laufen haben".)
net.minecraft.client.entity EntityPlayerSP player Spieler-Instanz der aktuellen Welt (null wenn wir in keiner Welt sind, sondern nur eine GUI "am laufen haben".)
net.minecraft.util Session session Instanz der aktuellen Sitzung (Wie man diese ändern kann, und sich somit in einen anderen Minecraft-Account einloggen, erkläre ich später)
boolean isGamePaused Notiz: Wenn wir im Single-Player spielen, und ins Pause Menü gehen, wird das Spiel pausiert. Nicht aber so im Multiplayer.
net.minecraft.client.gui FontRenderer fontRenderer (MCP-Kommentar: "The font renderer used for displaying and measuring text")
net.minecraft.client.gui GuiScreen currentScreen Die aktuell angezeigte GUI(Screen-Instanz). (Mehr Infos über das GUI-System folgen)
net.minecraft.client.gui GuiIngame ingameGUI Die HUD-Oberfläche des Spiels. Da die Ingame-HUD eine seperate GUIScreen-Variable ist, kann gleichzeitig das Pause-Menü sowie das eigentliche Spielgeschehen angezeigt werden.
net.minecraft.client.settings GameSettings gameSettings Die akutellen Spiele-Einstellungen
java.io File mcDataDir .minecraft-Ordner
net.minecraft.client.settings GameSettings gameSettings (MCP-Kommentar: "The game settings that currently hold effect.")
int debugFPS Wird jeden Frame, der im F3-Menü verbracht wird, auf die kalkulierte FramesPerSecond gesetzt.
boolean inGameHasFocus Gibt an, ob das eigentliche Gameplay Fokus hat. Wenn ja werden Maus/Tastatur einfluss auf das Spiel haben, anderenfalls auf die aktive GUI.
boolean isDemo Notiz: Da dies nur ein einfacher boolean ist, und keine weiteren Checks stattfinden, könnte man ganz einfach einen "Crack-Clienten" programmieren, mit den man dann normal (aber ohne Multiplayer weil ja immernoch Premium fehlt) spielen kann, als hätte man es gekauft.
Bitte beachte aber die Lizenzbedingungen: "You are not allowed to: ...Release Minecraft versions or modifications that allow you to play without having bought Minecraft from Mojang."

Grafische Benutzeroberflächen

net.minecraft.client.gui

Gui

Jegliches GUI-Objekt erbt von der Klasse Gui. Diese Klasse ist aber nur als eine Hilfsklasse anzusehen, da sie nur Methoden zum zeichnen bietet.

  • Dennoch gibt es eine spezifische Objekt-Variable, welche auch beim rendern beachtet wird und weswegen die Methoden nicht statisch sind, und zwar: zLevel

Die wichtigsten Methoden:

Variable Beschreibung
void drawRect(int left, int top, int right, int bottom, int color) Zeichnet ein einfarbiges Rechteck mit den angegebenen Koordinaten und Farben.
void drawHorizontalLine(int startX, int endX, int y, int color)
void drawVerticalLine(int x, int startY, int endY, int color)
Zeichnet eine schmale Linie zwischen den 2 angegebenen Punkten mit der angegebenen Farbe
void drawGradientRect(int left, int top, int right, int bottom, int startColor, int endColor) Zeichnet ein Rechteck mit einem vertikalen Verlauf zwischen den angegebenen Farben (im ARGB-Format).
void drawCenteredString(FontRenderer fontRendererIn, String text, int x, int y, int color) Zeichnet den angegebenen String, wobei der x-Parameter der Mittelpunkt des Textes sein sollte
drawModalRectWithCustomSizedTexture(int x, int y, float u, float v, int width, int height, float textureWidth, float textureHeight) Zeichnet ein Rechteck mithilfe der Textur, die derzeitig im RenderManager registriert ist

GuiScreen

Jede Oberfläche/jedes Menü, das man im Spiel sehen kann, ist eine Implementation der abstrakten Klasse GuiScreen, welche wiederum von Gui erbt.
Diese Klasse besitzt schon viel mehr Methoden und Logik, welche für eine Oberfläche von nöten sind.

Die aktuell angezeigte GUI wird in der Variable currentScreen der Klasse net.minecraft.client.Minecraft abgespeichert.

  • Mithilfe der Methode displayGuiScreen(GuiScreen screen) der Klasse net.minecraft.client.Minecraft kann diese auf eine neues Objekt zeigen (Setter).
    • Falls beim Methoden-Aufruf es schon ein currentScreen-Objekt gab, wird diesem Objekt mithilfe von .onGuiClosed() mitgeteilt, dass es ersetzt wird
    • Falls die neue, angegebene GuiScreen Instanz nicht null entspricht, wird diese mithilfe von .setWorldAndResolution(Minecraft mc, int width, int height) zum initiieren ihrer GUI-Objekte (Buttons, ...) aufgefordert.

Die wichtigsten:

Variable Beschreibung
Methoden, die zum überschreiben gedacht sind und an sich keine richtige Logik beinhalten.
void initGui(int mouseX, int mouseY, float partialTicks) MCP-Kommentar: Adds the buttons (and other controls) to the screen in question. Called when the GUI is displayed and when the window resizes, the buttonList is cleared beforehand.
void drawScreen(int mouseX, int mouseY, float partialTicks) MCP-Kommentar: Draws the screen and all the components in it.
void updateScreen() MCP-Kommentar: Called from the main game loop to update the screen.
void onGuiClosed() MCP-Kommentar: Called when the screen is unloaded. Used to disable keyboard repeat events
void keyTyped(char typedChar, int keyCode) MCP-Kommentar: Fired when a key is typed (except F11 which toggles full screen). This is the equivalent of KeyListener.keyTyped(KeyEvent e).
  • typedChar: Charakter (Kann leer sein)
  • keyCode: LWJGL-Keycode, siehe Klasse org.lwjgl.input.Keyboard für eine Auflistung aller Konstanten
void mouseClicked(int mouseX, int mouseY, int mouseButton) MCP-Kommentar: Called when the mouse is clicked.
void mouseReleased(int mouseX, int mouseY, int state) MCP-Kommentar: Called when a mouse button is released.
void mouseClickMove(int mouseX, int mouseY, int clickedMouseButton, long timeSinceLastClick) MCP-Kommentar: Called when a mouse button is pressed and the mouse is moved around.
void actionPerformed(GuiButton button) MCP-Kommentar: Called by the controls from the buttonList when activated. (Mouse pressed for buttons)
boolean doesGuiPauseGame() MCP-Kommentar: Returns true if this GUI should pause the game when it is displayed in single-player
Helper-Methoden
boolean isCtrlKeyDown() Gibt true zurück, wenn [CTRL] (bei Windows) oder [META] (bei MAC) gedrückt wird
boolean isShiftKeyDown() Gibt true zurück, wenn einer der beiden [SHIFT]-Tasten gedrückt wird (links/rechts)
boolean isAltKeyDown() Gibt true zurück, wenn einer der beiden [ALT]-Tasten gedrückt wird (links/rechts)
boolean isKeyComboCtrlX(),

boolean isKeyComboCtrlC(),
boolean isKeyComboCtrlV(),
boolean isKeyComboCtrlA()

Gibt true zurück, wenn [X/C/V/A] und [CTRL] gleichzeitig gedrückt werden, UND isShiftKeyDown sowie isAltKeyDown false zurückgeben.
String getClipboardString() Wenn sich im System-Clipboard ein String befindet, gibt es diesen zurück, ansonsten "".
void setClipboardString(String copyText) Speichert den angegebenen String im System-Clipboard
boolean isFocused()
void setFocused(boolean focus)
void openWebLink(URI url)
void drawHoveringText(List<String> textLines, int x, int y) und drawHoveringText(String text, int x, int y) MCP-Kommentar: Draws a List of strings as a tooltip. Every entry is drawn on a seperate line.
void drawHoveringText(String text, int x, int y) Ruft die obrige Methode mit nur einer Zeile auf. (Mithilfe von Arrays.asList(text))
void renderToolTip(ItemStack stack, int x, int y) Ruft drawHoveringText, mit .getItemToolTip(stack) als textLines-Argument, auf
void drawDefaultBackground() MCP-Kommentar: Draws either a gradient over the background screen (when it exists) or a flat gradient over background.png

Jedes GuiScreen-Objekt besitzt eine Liste an GuiButtons, gespeichert in der Variable buttonList.

  • Diese Liste kann beim initiieren initGui() von der jeweiligen Implementation mit den gewünschten Inhalt befüllt werden.
  • Durch diese Liste regelt die GuiScreen-Klasse automatisch, ob die "Klick-Region" einen Knopf beinhaltet, und ruft ggf. actionPerformed(GuiButton button) auf (Damit die individuelle GuiScreen-Implementation auf den Klick einfach reagieren kann)

GuiIngame

Die Klasse net.minecraft.client.gui.GuiIngame stellt das HUD im Spiel dar.
Die GuiIngame-Instanz wird seperat zum derzeitigen GuiScreen in der Variable guiIngame der Klasse net.minecraft.client.Minecraft abgespeichert, und beim starten (innerhalb der Methode init) initiiert.

  • Diese seperierung der grafischen Benutzeroberflächen ermöglicht es, dass Spiel-Geschehen zu sehen während man sich gleichzeitig im Pause/Einstellungs-Menü befindet.

FontRenderer

Die net.minecraft.client.gui.FontRenderer-Klasse wird...

  • zum einfachen rendern eines Textes in mit verschiedenen Styles in einer gewissen Schriftart
  • sowie zur einfachen Berechnung der Breite/Höhe, die ein Text einnehmen wird

... verwendet.
Die Standard FontRenderer-Instanz ist über die Variable fontRenderer der Klasse net.minecraft.client.Minecraft erreichbar.

Die wichtigsten Methoden:

Variable Beschreibung
int renderString(String text, float x, float y, int color, boolean dropShadow) Haupt-Methode, welche von allen anderen render/draw-Methoden aufgerufen wird
  • color: (A)RGB-Farbwert (Beispiel im Hex-Format: 0x[ALPHA][RED][GREEN][BLUE], 0xFFFFFFFF für 100% WEISS)
  • dropShadow: Zeichnet den gleichen String nocheinmal mit einer kleinen Verschiebung und anderem Farbwert, um einen Schatten-Effekt zu simulieren
  • Falls der text nicht leer ist, gibt es die angegebene x-Position zurück (NICHT ABER SO BEI renderStringAligned). Ansonsten 0
int drawString(String text, float x, float y, int color, boolean dropShadow) Setzt mithilfe von resetStyle() alle Styles zurück, aktviert den OpenGL ALPHA-Wert und ruft anschließend renderString(String text, float x, float y, int color, boolean dropShadow) auf
int drawStringWithShadow(String text, float x, float y, int color) Ruft die obrige Methode mit dropShadow = true aus.
int drawString(String text, int x, int y, int color) Eine Methoden-Überladung für die erst-genannte drawString()-Methode mit dem Standardwert dropShadow = true.
int renderStringAligned(String text, int x, int y, int width, int color, boolean dropShadow) Wenn von rechts-nach-links geschrieben wird (Aka. bidiFlag auf true gesetzt ist), wird der x-Parameter zuerst so abgeändert, dass es vom rechten rand ausgeht - und danach die normale renderString-Methode aufgerufen
void drawSplitString(String str, int x, int y, int wrapWidth, int textColor) Setzt mithilfe von resetStyle() alle Styles zurück, Teilt den String in mehrere Zeilen auf und zeichnet diese mithilfe von renderSplitString(String str, int x, int y, int wrapWidth, boolean addShadow) (sog. Wordwrapping)
getStringWidth(String text) Gibt die Breite des Strings zurück
getCharWidth(char character) Gibt die Breite des chars zurück
String trimStringToWidth(String text, int width, boolean reverse) Schneidet den String so zurecht, dass er in den angegebenen Bereich passt
void getWordWrappedHeight(String str, int maxLength) Gibt die Höhe (in Pixel) des Strings in Pixel zurück, wenn dieser mithifle von maxLength in mehrere Zeilen aufgeteilt wird. (sog. Wordwrapping)

Packete

net.minecraft.client.network, net.minecraft.network net.minecraft.client.multiplayer

Packet

NetworkManager

NetHandlerPlayerClient

NetworkPlayerInfo

PlayerControllerMP

Spieler & Welt

net.minecraft.entity + net.minecraft.client.multiplayer

Entity

WorldClient

EntityPlayerSP

Einstellungen

net.minecraft.client.settings

GameSettings

Eigenen Features einbauen: Vorgehensweisen

Events

Um nicht immer im Sourcecoude von Minecraft Sachen bearbeiten/nachschauen zu müssen, geht man meist so vor dass man bei Methoden/Aktionen die von Minecraft aufgerufen werden, einfach nur ein "Event" broadcastet, mithilfe dessen dann dein Client darauf reagieren kann.

  • Somit hat man im Minecraft-Source nur ein paar Zeilen verändert, und die eigentliche Logik kann in seinem eigenen Packet verweilen und einfach bearbeitet werden
  • Nach dem gleichen Prinzip geht auch Spigot/Bukkit vor.

Beispiel eines OpenSource Java EventManager-Systems

Typische MCP-Events

Typische MCP-Events könnten sein:

Event2D

Zum rendern von Ingame HUD-Elemente. (Beispiel-Interaktion: Mithilfe des FontRenderers die derzeitigen FPS anzeigen)

> Wo wird es aufgerufen:
Innerhalb der Methode renderGameOverlay(float partialTicks) der Klasse GuiIngame nach dem else-Tag von this.renderHotbar(scaledresolution, partialTicks);.

> Nützliche Parameter zum mitsenden wären:

  • scaledResolution,
  • partialTicks und
  • this (Da GuiIngame von Gui erbt und somit nützliche Render-Methoden bietet)

Event3D

Zum rendern von Ingame-Elementen. (Beispiel-Interaktion: Eine Box um jeden Spieler in der Welt zeichnen)

> Wo wird es aufgerufen:
Innheralb der Methode renderWorldPass(int pass, float partialTicks, long finishTimeNano) der Klasse EntityRenderer, vor this.mc.mcProfiler.endStartSection("hand");.

> Nützliche Parameter zum mitsenden wären:

  • partialTicks

EventKeyPressed

Zum interagieren von Tastatur-Eingaben.

> Wo wird es aufgerufen:
Innheralb der Methode runTickKeyboard() der Klasse Minecraft, vor if (i == 1).

> Nützliche Parameter zum mitsenden wären:

  • i (LWJGL-Keycode, siehe Klasse org.lwjgl.input.Keyboard für eine Auflistung aller Konstanten)

EventPlayerUpdate

Zum interferieren mit den Spieler-Logikupdates. (Beispiel-Interaktion: Immer Sprinten, wenn der Spieler läuft)

> Wo wird es aufgerufen:
Innheralb der Methode onUpdate() der Klasse EntityPlayerSP, nach super.onUpdate();.

> Nützliche Parameter zum mitsenden wären:

  • this

EventPreMotionUpdate

Wie EventPlayerUpdate, zum interferieren der folgenden Spieler-Bewegungen. (für zB.: Speed)

> Wo wird es aufgerufen:
Innheralb der Methode onUpdate() der Klasse EntityPlayerSP, vor dem Aufruf von this.onUpdateWalkingPlayer();.

> Nützliche Parameter zum mitsenden wären:

  • xPos
  • yPos
  • zPos
  • rotationYaw
  • rotationPitch
  • onGround

Nach dem das Event aufgerufen wurde, und somit etwaige Zuhörer die obrigen Event-Parameter verändert haben, sollte man die eigentlichen EntityPlayerSP-Variablen auf diese neuen "Event-Werte" setzen.

EventPostMotionUpdate

Wie EventPreMotionUpdate, ausser dass es nach allen eigentlichen Spielupdate-bewegungen stattfindet. (für zB.: LongJump)

> Wo wird es aufgerufen:
Innheralb der Methode onUpdate() der Klasse EntityPlayerSP, nach dem Aufruf von this.onUpdateWalkingPlayer();.

EventPacketReceived

Zum auffangen von Packeten die ankommen, bevor Sie von Minecraft vearbeitet wurden. + Das Event sollte Abbrechbar sein, so dass Events bestimmen können ob das Packet verarbeitet werden soll oder einfach weggeworfen. (Beispiel-Interaktion: sog. "AntiBots" von AntiCheat-Plugins daran hintern zu spawnen, indem man das Packet S0CPacketSpawnPlayer nach gewissen Checks (Ist es in der nähe gespawnt, ist es unsichtbar, seine ID, ...) abbricht.)

> Wo wird es aufgerufen:
Innheralb der Methode channelRead0(ChannelHandlerContext handlerContext, Packet<?> packet) der Klasse NetworkManager, vor ((Packet<INetHandler>)p_channelRead0_2_).processPacket(this.packetListener); innherhalb der try-catch-Klausel.

> Nützliche Parameter zum mitsenden wären:

  • packet


EventPacketSendRequest

Zum auffangen von Packeten die gesendet werden sollen, bevor Sie geschickt werden. + Das Event sollte Abbrechbar sein, so dass Events bestimmen können ob das Packet gesendet werden soll oder einfach weggeworfen. (Beispiel-Interaktion: Etwas machen wenn der Spieler schlägt, siehe C02PacketUseEntity. [7])


> Wo wird es aufgerufen:
Direkt am Anfang der Methode sendPacket(Packet<?> packetIn) der Klasse NetworkManager.

> Nützliche Parameter zum mitsenden wären:

  • packetIn


EventPacketSent

Zum abchecken von Packeten die gerade gesendet wurden.

> Wo wird es aufgerufen:
Am ende der Methode dispatchPacket(final Packet<?> inPacket, @Nullable final GenericFutureListener <? extends Future <? super Void >> [] futureListeners) der Klasse NetworkManager.

> Nützliche Parameter zum mitsenden wären:

  • inPacket

EventClientShutdown

Zum schließen aller Connections und etwaigen Speichern von Java-Objekten in Dateien, damit sie beim nächsten Anruf noch behalten bleiben und nicht erlischen.

> Wo wird es aufgerufen:
Innheralb der Methode shutdownMinecraftApplet() der Klasse Minecraft, nach LOGGER.info("Stopping!");.

EventClientStartup

Zum intialisieren von Client-Komponenten.

> Wo wird es aufgerufen:
Am ende der Methode init() der Klasse Minecraft.


Module

Eigene HUD-Elemente

Eigene GuiScreens