Kleinste freie Zahl

@cmrudolph Ich interresiere mich noch für das Thema, ich brauche blos etwas länger , um das alles hier zu verstegen

Freut mich zu hören. Lass dir ruhig Zeit und frag gezielt nach.
Du hast jetzt ja einen Haufen Ideen präsentiert bekommen. Damit das aber nicht in eine vollkommen falsche Richtung geht, wäre es wahrscheinlich hilfreich, wenn du deine Klasse posten würdest (auch die Pluginklasse).
Zumindest sah der von dir gepostete Code so aus, als wenn es da noch etwas Optimierungspotenzial gibt, was das Softwaredesign angeht. Zumindest, wenn du dich nicht mit einer „hauptsache läuft“-Lösung zufrieden gibst.

[QUOTE=Blackbyte] @cmrudolph Ich interresiere mich noch für das Thema, ich brauche blos etwas länger , um das alles hier zu verstegen[/QUOTE]Öhm… ich auch. :wink:
Zumindest, was meine Frage mit der Map angeht und ob es nötig ist, diese IDs in einer solchen abzulegen?

Eine Map oder eine List füllt sich ja nach dem Prinzip elements[Index] = index, wobei für jeden Wert ein neues Objekt mit mindestens 8 Byte angelegt wird. Ein BitSet hingegen signalieiert nur verwendet oder nicht verwendet und ist dauerhaft sortiert (logisch nicht wahr ;)). Die IDs selber lassen sich ja auch iin jenen Objekten speichern, die sie anfordern und dort per Getter ermitteln.

@cmrudolph :
Den Sinn von AtomicInteger verstehe ich an dieser Stelle jedoch nicht bzw. halte ich das für diesen Zweck für ein wenig überzogen.

@Spacerat :

Du zieltest mit dem synchronisieren ja auf Threadsicherheit ab. (Wobei wir noch gar nicht wissen, ob die Klasse überhaupt threadsicher sein muss.)
Wenn sie threadsicher sein soll, ist es besser, nicht gleich über dem ganzen Objekt zu synchronisieren. Denn es gibt wahrscheinlich keinen Grund, weshalb bei einem Zugriff auf die senderMap der Zugriff auf die receiverMap geblockt werden sollte.

[quote=Blackbyte;98501]Jeder Sender und jeder Empfänger hat eine ID.
Man brauch die ID,da jeder Sender auch mehrere Empfänger haben kann.[/quote]
Das verstehe ich nicht so ganz. Was ich daraus mitgenommen habe ist, dass für jeden Sender und Empfänger eine zugehörige ID generiert werden soll.
Er möchte seine IDs jetzt so generieren, dass einfach die erste freie gewählt wird. Das erkennt er mit seinem Ansatz daran, dass er in einer Schleife prüft, ob eine ID bereits vergeben ist.

Unter der Annahme, dass die IDs wirklich nur Identifikatoren sind und dass es egal ist, wenn es Lücken zwischen den IDs gibt, wäre ein sinnvoller Ansatz, einfach einen Zähler zu verwenden.

Um den Argumentationskreis nun zu schließen:
Minimales Locking erreicht man bei einer Map, indem man die ConcurrentHashMap verwendet. Das macht das bisherige Vorgehen die IDs durch Suchen zu finden unmöglich, weil man Nebenläufigkeitsprobleme bekommen wird (die Suchschleife ist schließlich nicht mehr synchronisiert).
Einfacher ist es daher, einen einfachen Zähler zu verwenden. Und um diesen mit minimalem Locking zu erstellen, nutzt man einfach ein AtomicInteger.

Ein AtomicInteger lässt sich mMn nicht schwieriger verwenden, als ein ganz normales Integer-Objekt. Daher finde ich nicht, dass es überzogen ist.

@cmrudolph :
Also AtomicInteger anstelle von Bitset, weil man sich dann noch die Synchronisation spart und dann auch nicht zum Speichern in einer Map, sondern nur zum Erstellen von IDs. Ok genehmigt.
Ich hätte sonst in den beiden next-Methoden schlicht auf die jeweiligen Bitsets syncronisiert und fertig. z.B.:

    synchronized(senderIDs) {
      int rc = senderIDs.nextClearBit(fromIndex);
      senderIDs.set(rc);
      return rc;
    }
  }```

Zuletzt frage ich mich noch, ob es sinnvoll ist, statt Sender und Empfänger getrennt zu handeln, SendeEmpfänger zu implementieren. IDs würden sich dann nämlich über IP- bzw. Mac-Addressen ergeben.

Genau so meinte ich das.

Ja, das wäre auch eine gangbare Lösung.
Wahrscheinlich wäre die Lösung sogar optimal, wenn nur ein Überblick gehalten werden soll, welche IDs vergeben sind und welche nicht.
Wenn man nach dem Freiwerden einer ID die Lücke wieder füllen, aber trotzdem die Objekte in einer Map speichern möchte, kann man diesen Ansatz sicherlich gut verwenden, um die IDs zu generieren.

@cmrudolph ich werde meine Klasse bald Posten, ich will blos noch eine besser Lösung draus machen. @Spacerat es geht hier um Minecraft Empfänger und Sender für ein Kabel

[QUOTE=Blackbyte]@Spacerat es geht hier um Minecraft Empfänger und Sender für ein Kabel[/QUOTE]Ähh… Mehrere SendeEmpfänger pro IP-/Mac-Addresse?

Gar nichts mit IP oder Mac-Adresse.
Es geht um Ingame. Google einfach mal Minecraft Redstone , blos das Wirless

Ingame besteht stets eine Client-Server-Konstellation, die man per IP-Adresse (eindeutige ID) identifizieren kann, jedenfalls ist das bei vielen Onlinegames (afaik bei allen) so. Über diese Adresse lassen sich P2P-Konstellationen innerhalb des gesamten Spielenetzwerks etablieren, ohne dass man dazu irgendwelche neuen IDs vergeben muss. Selbst erstellte IDs wären nur dann notwendig, wenn mehrere Spielclients auf einem Rechner laufen sollen, dieses muss dann aber auch vom verwendeten TCP/IP- bzw. UDP-Protokoll (kurz, internem Spielprotokoll) unterstützt werden. Poste einfach mal das Projekt, damit man erkennen kann, was du vorhast.

wie kommst du ohne Anlass auf IP, Mac-Adresse, P2P-Konstellationen?
und es wurden ja schon Korrekturhinweise gegeben,

es geht um reine Spiellogik, Stromkabel zwischen Geräten/ Schaltern mit Nummer/ Id 1, 2, 3 usw. (auch nur halb vermutet, aber gewiss doch richtigere Richtung)

Du verstehst immer noch nicht, was ich meine: Es geht hier nicht um das, sondern so etwas wie WLAN in Minecraft.

#FürProjektVorbehaltenImmoEntwicklungsstoppDaIchGeradeZocke :smiley:

Edit: @SlaterB war mal wieder schneller: Genau du hast es erfasst

Ahhh… ok. :o
(evtl. hätte ich Netzwerk-Simulation besser verstanden ;))

@Spacerat immer diese Fachbegriffe :open_mouth: :wink:

Für Thread-Tests ist folgende ‘main’-Methode ein ganz guter Ansatz und Ausgabe:
[spoiler]```/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package javaapplication1;

import java.util.Arrays;
import java.util.HashSet;
import java.util.PriorityQueue;

/**

  • @author CB
    */
    public class IDsGen {

    private static IDsGen idsGen = null;
    private HashSet hsi = new HashSet();
    private PriorityQueue pqi = new PriorityQueue(Arrays.asList(1));
    private int big = 2;

    public static synchronized IDsGen newIDsGen() {
    if (idsGen == null) {
    return idsGen = new IDsGen();
    }
    return idsGen;
    }

    private IDsGen() {
    }

    public synchronized int nextID() {
    if (pqi.isEmpty()) {
    pqi.add(big++);
    }
    int i = pqi.remove();
    hsi.add(i);
    return i;
    }

    public synchronized boolean removeID(int id) {
    if (hsi.contains(id)) {
    hsi.remove(id);
    pqi.add(id);
    return true;
    }
    return false;
    }

    public static void main(String[] args) throws InterruptedException {
    final IDsGen IDS_GEN = IDsGen.newIDsGen();
    Runnable r = new Runnable() {
    @Override
    public void run() {
    String s = Thread.currentThread().toString();
    for (int i = 0; i < 1/00/; i++) {
    boolean b1 = Math.random() < 0.5;
    boolean b2 = Math.random() < 0.5;
    int j = (int) (Math.random() * 100.0) + 1;
    if (b1 || b2) {
    System.out.println(s + " : nextID = " + IDS_GEN.nextID());
    } else {
    System.out.println(s + " : removeID " + j + " = " + IDS_GEN.removeID(j));
    }
    }
    }
    };
    Thread[] ta = new Thread[100];
    for (int i = 0; i < ta.length; i++) {
    ta** = new Thread®;
    }
    for (Thread thread : ta) {
    thread.start();
    }
    for (Thread thread : ta) {
    thread.join();
    }
    System.out.println(“Fertig”);
    }
    }```

run:
Thread[Thread-0,5,main] : nextID = 1
Thread[Thread-1,5,main] : removeID 20 = false
Thread[Thread-2,5,main] : removeID 41 = false
Thread[Thread-10,5,main] : nextID = 9
Thread[Thread-9,5,main] : nextID = 7
Thread[Thread-4,5,main] : nextID = 8
Thread[Thread-7,5,main] : nextID = 6
Thread[Thread-6,5,main] : nextID = 4
Thread[Thread-8,5,main] : nextID = 5
Thread[Thread-5,5,main] : nextID = 2
Thread[Thread-3,5,main] : nextID = 3
Thread[Thread-17,5,main] : nextID = 10
Thread[Thread-11,5,main] : nextID = 11
Thread[Thread-16,5,main] : removeID 50 = false
Thread[Thread-14,5,main] : nextID = 12
Thread[Thread-13,5,main] : nextID = 13
Thread[Thread-19,5,main] : removeID 69 = false
Thread[Thread-20,5,main] : nextID = 14
Thread[Thread-33,5,main] : nextID = 15
Thread[Thread-72,5,main] : removeID 72 = false
Thread[Thread-73,5,main] : nextID = 55
Thread[Thread-27,5,main] : nextID = 56
Thread[Thread-69,5,main] : nextID = 57
Thread[Thread-67,5,main] : nextID = 58
Thread[Thread-98,5,main] : nextID = 59
Thread[Thread-64,5,main] : nextID = 60
Thread[Thread-96,5,main] : nextID = 54
Thread[Thread-99,5,main] : nextID = 62
Thread[Thread-66,5,main] : nextID = 21
Thread[Thread-71,5,main] : nextID = 53
Thread[Thread-74,5,main] : nextID = 52
Thread[Thread-60,5,main] : nextID = 63
Thread[Thread-76,5,main] : nextID = 51
Thread[Thread-75,5,main] : nextID = 50
Thread[Thread-93,5,main] : nextID = 49
Thread[Thread-78,5,main] : nextID = 48
Thread[Thread-77,5,main] : nextID = 47
Thread[Thread-81,5,main] : removeID 92 = false
Thread[Thread-86,5,main] : nextID = 46
Thread[Thread-79,5,main] : nextID = 45
Thread[Thread-50,5,main] : nextID = 44
Thread[Thread-97,5,main] : removeID 56 = false
Thread[Thread-80,5,main] : nextID = 43
Thread[Thread-83,5,main] : nextID = 42
Thread[Thread-85,5,main] : nextID = 41
Thread[Thread-95,5,main] : nextID = 40
Thread[Thread-94,5,main] : removeID 76 = false
Thread[Thread-92,5,main] : nextID = 39
Thread[Thread-91,5,main] : nextID = 38
Thread[Thread-90,5,main] : removeID 98 = false
Thread[Thread-88,5,main] : nextID = 16
Thread[Thread-89,5,main] : removeID 16 = true
Thread[Thread-84,5,main] : nextID = 37
Thread[Thread-37,5,main] : removeID 37 = false
Thread[Thread-53,5,main] : nextID = 36
Thread[Thread-34,5,main] : nextID = 35
Thread[Thread-82,5,main] : nextID = 34
Thread[Thread-51,5,main] : nextID = 33
Thread[Thread-48,5,main] : nextID = 32
Thread[Thread-45,5,main] : nextID = 31
Thread[Thread-42,5,main] : nextID = 30
Thread[Thread-44,5,main] : nextID = 29
Thread[Thread-31,5,main] : nextID = 22
Thread[Thread-35,5,main] : removeID 22 = true
Thread[Thread-32,5,main] : removeID 84 = false
Thread[Thread-29,5,main] : removeID 29 = false
Thread[Thread-30,5,main] : nextID = 28
Thread[Thread-28,5,main] : nextID = 19
Thread[Thread-70,5,main] : removeID 19 = true
Thread[Thread-65,5,main] : nextID = 27
Thread[Thread-62,5,main] : nextID = 26
Thread[Thread-63,5,main] : nextID = 25
Thread[Thread-26,5,main] : nextID = 24
Thread[Thread-23,5,main] : removeID 68 = false
Thread[Thread-24,5,main] : nextID = 23
Thread[Thread-21,5,main] : nextID = 22
Thread[Thread-56,5,main] : nextID = 21
Thread[Thread-15,5,main] : nextID = 20
Thread[Thread-22,5,main] : nextID = 19
Thread[Thread-12,5,main] : nextID = 18
Thread[Thread-47,5,main] : nextID = 17
Thread[Thread-41,5,main] : removeID 57 = false
Thread[Thread-39,5,main] : removeID 53 = false
Thread[Thread-38,5,main] : nextID = 16
Thread[Thread-36,5,main] : removeID 29 = false
Thread[Thread-43,5,main] : nextID = 38
Thread[Thread-40,5,main] : nextID = 30
Thread[Thread-46,5,main] : nextID = 16
Thread[Thread-49,5,main] : removeID 16 = true
Thread[Thread-52,5,main] : removeID 30 = true
Thread[Thread-55,5,main] : nextID = 37
Thread[Thread-18,5,main] : removeID 55 = true
Thread[Thread-58,5,main] : removeID 45 = true
Thread[Thread-54,5,main] : removeID 37 = true
Thread[Thread-87,5,main] : removeID 92 = false
Thread[Thread-59,5,main] : removeID 38 = true
Thread[Thread-57,5,main] : nextID = 64
Thread[Thread-25,5,main] : removeID 21 = true
Thread[Thread-61,5,main] : nextID = 61
Thread[Thread-68,5,main] : removeID 80 = false
Fertig
BUILD SUCCESSFUL (total time: 0 seconds)

[/spoiler]

Daran sieht man, dass Threads immer unterschiedlich abgearbeitet werden (nicht der Reihenfolge nach). Außerdem kann es ein nextID x und ein removeID x = false (in dieser Reihenfolge) als Ausgabe geben, weil zwei Threads gleichzeitig abgearbeitet werden.

Also ist Synchronisierung bei Threads wichtig. Aber nextID( und removeID( kann nicht anders, über einen kleineren Bereich synchronisiert werden, da alle 3 - 4 Anweisungen unbedingt zusammenhängend durchlaufen werden müssen, Abhängigkeiten. Thread-sichere Datenstruktur(en) wäre dann doppelt synchronisiert und nicht benötigt.

BitSet vs. HashSet & PriorityQueue wäre auch gut, aber dann wird 1.) mehr Speicherplatz für das Bit/Byte-Array benötigt und 2.) steigt die Laufzeit von O/T(log(n)) auf O/T(n/2) bzw. n für jede (Einfügen/Uneinfügen) Operation .

@Blackbyte : Mit Bucket, Minecraft, Redstone, Wirless usw. kennt sich hier keiner aus. Ich weiß zwar, was Minecraft ist, ein Game, das mit .java-Dateien erweiterbar ist, aber Bucket, da hört es bei mir schon auf. Eventuell Dein Problem vom Konkretem zum Allgemeinen/Abstraktem analysieren/abstrahieren/reduzieren (nach K. Marx).

[QUOTE=CyborgBeta]BitSet vs. HashSet & PriorityQueue wäre auch gut, aber dann wird 1.) mehr Speicherplatz für das Bit/Byte-Array benötigt und 2.) steigt die Laufzeit von O/T(log(n)) auf O/T(n/2) bzw. n für jede (Einfügen/Uneinfügen) Operation .[/QUOTE]Ahh… ja. Du meinst also das BitSet wäre ein simples Bit/Bytearray und frisst damit mehr Speicher als ein HashSet oder eine PriorityQueue? Mach dich mal mit dem Sinn von BitSet vertraut, bevor du solche (ehrlich gesagt) Troll-Beiträge verfasst. Ein BitSet verwendet pro 64 Bit nur ein long, welche in einem Array gespeichert werden, dessen Größe sich je nach Bedarf vergrößert (im Zweifelsfalle verdoppelt).

Och Space, theoretisch braucht ein BitSet 1 Speichereinheit für ein Element, und es kann (wegen der Lücken) locker 10x so viele Elemente geben, wie eine HashSet benötigen würde. Also weder „Troll-Betrag“ noch „Anfänger-Beitrag“ zählt/zählen. :stuck_out_tongue: Auch Moderatoren müssen sich mal zügeln. :stuck_out_tongue: Bye, icke bin off.

[QUOTE=CyborgBeta]Och Space, theoretisch braucht ein BitSet 1 Speichereinheit für ein Element, und es kann (wegen der Lücken) locker 10x so viele Elemente geben, wie eine HashSet benötigen würde. Also weder „Troll-Betrag“ noch „Anfänger-Beitrag“ zählt/zählen. :stuck_out_tongue: Auch Moderatoren müssen sich mal zügeln. :stuck_out_tongue: Bye, icke bin off.[/QUOTE]Guter Mann…
Im BitSet benötigen 64 Bits ein long bzw 8 Bytes (geringfügig mehr), wohingegen ein boolean-Array für jedes Bit exakt 8 mal mehr Speicher ver(sch)wendet. Ca. alle n * 64 Bit wird das long-Array im BitSet vergrössert, und mit jedem long in diesem Array Platz für weitere 64 Bit geschaffen. Maw.: mit einem Element in der Wordlist eines BitSets können 64 Bits bedient werden. Ein HashSet würde pro Bit also ca. 64 mal so viele Elemente wie BitSet verwenden.
Deshalb stets beachten: Befasse dich eindringlicher mit der Materie, bevor man dir in Foren (oder viel Schlimmer in Schule/Beruf) die Hosen runter zieht.

Nun aber Schluss mit OT.

Ne, du hast dich nicht mit der Materie befasst, ich sprach vom Theoretischen, O(64n) ist das Gleiche wie O(n) [theoretisch], aber wenn es die IDs 1 und 5000 gibt, braucht die HashSet k2 Speicherplatz und die BitSet mind. 5000/k==5000/64 Speicherplatz [praktisch], das wäre dann 78-mal so viel. Klar kann es in der Praxis kleiner/schneller sein, jedoch nicht in der Theorie [O-Notation].

Aber wenn er das selber bauen will, würde ich auch an eine BitSet denken.

Es wäre auch nicht schlecht, die BitSet oder die HashSet irgendwann zu verkleinern, also zu reorganisieren.

private int big = dürfte auch nicht negativ werden, afaik sonst crasht es irgendwann.

Nimm „meine“ Variante/Lösung doch einfach als gegeben hin sowie meine Begründung und sag’: 1, setzen! :slight_smile: Dankeschön.

@ BB/TO : Gibt es noch weiteren source code?

@CyborgBeta ich kann leider blos erstmal den alten posten,jeddoch hier ist er:


import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;

import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitRunnable;

import de.Blackbird.MinigameAPI.Command.CommandAPI;
import de.Blackbird.MinigameAPI.Command.Permissions.PermissionCommand;
import de.Blackbird.MinigameAPI.Database.DatabaseAPI;
import de.Blackbird.MinigameAPI.Database.DatabaseConfig;
import de.Blackbird.MinigameAPI.Economy.EconomyAPI;
import de.Blackbird.MinigameAPI.FastType.FastType;
import de.Blackbird.MinigameAPI.IngameShop.IngameShopAPI;
import de.Blackbird.MinigameAPI.Language.LanguageAPI;
import de.Blackbird.MinigameAPI.Listeners.PlayerChatFormatListener;
import de.Blackbird.MinigameAPI.Listeners.PlayerJoinListener;
import de.Blackbird.MinigameAPI.Permission.Group;
import de.Blackbird.MinigameAPI.Permission.PermissionAPI;
import de.Blackbird.MinigameAPI.Scoreboard.ScoreboardAPI;
import de.Zorro909.MinigameAPI.Arena.Arena;
import de.Zorro909.MinigameAPI.Arena.ArenaAPI;
import de.Zorro909.MinigameAPI.Arena.ArenaListener;

public class MinigameAPI extends JavaPlugin {

	private static MinigameAPI instance;
	private DatabaseAPI database;
	private EconomyAPI economy;
	private LanguageAPI language;
	private CommandAPI commands;
	private IngameShopAPI ingameShop;
	private PermissionAPI permissions;
	private ScoreboardAPI scoreboard;
	private FastType fast;
	private GameState state;
	private ArenaAPI arena;
	private String name;
	private String consolePrefix = "[MinigameAPI]";
	private Map<Arena, ArenaGameState> gameStateMap;

	public void onEnable() {
		System.out.println(consolePrefix + "Starting MinigameAPI......");
		state = GameState.LOBBY;
		this.name = Bukkit.getServerName();
		instance = this;
		loadConfigs();
		loadAPI();
		registerListeners();		
		registerAllCommands();
		System.out.println(consolePrefix + "MinigameAPI sucessfully started.");
	}

	public void onDisable() {
		for (Player p : Bukkit.getOnlinePlayers()) {
			p.kickPlayer(MinigameAPI.getInstance().getLanguageAPI()
					.getString(p.getUniqueId(), "SERVER_SHUTDOWN"));
		}
		System.out.println(consolePrefix + "Disabling MinigameAPI......");
		try {
			language.savePlayerLanguages();
			economy.unloadAllEconomy();
			permissions.unloadGroups();

		} catch (Exception e) {
			this.getLogger()
					.severe("Ein schwerwiegernder Fehler ist aufgetreten während die Module entladen worden waren!");
			e.printStackTrace();

		}
		System.out.println(consolePrefix + "MinigameAPI sucessfully disabled.");
	}

	private void loadConfigs() {
		try {
			DatabaseConfig.load(instance, new File(
					"plugins/MinigameAPI/configs/database.yml"));
		} catch (IOException e) {
			this.getLogger()
					.severe("Ein Schwerwiegender Fehler ist aufgetretet während die Config geladen worden war.");
		}

	}

	private void loadAPI() {
		File languageDir = new File("plugins/MinigameAPI/language");
		try {
			database = new DatabaseAPI(instance);
			language = new LanguageAPI();
			economy = new EconomyAPI();
			commands = new CommandAPI();
			ingameShop = new IngameShopAPI();
			permissions = new PermissionAPI();
			fast = new FastType();
			scoreboard = new ScoreboardAPI();
			arena = new ArenaAPI();
			if (!languageDir.exists()) {
				languageDir.mkdirs();
			}
			registerDefaultLanguageStrings();
			registerDefaultGroups();
			registerFastTypes();
		} catch (Exception e) {
			this.getLogger()
					.severe("Ein schwerwiegender Error ist aufgetreten während die Api geladen worden ist!");
		}
	}

	private void registerDefaultLanguageStrings() {
		try {

			language.addLocale("DE");
			language.addLocale("EN");
			language.addLangString("PLAYER_JOIN");
			language.addLangString("PLAYER_LEFT");
			language.addLangString("PLAYER_KICK");
			language.addLangString("DEFAULT_BAN_MESSAGE");
			language.addLangString("SERVER_SHUTDOWN");
			language.addLangString("COMMAND_NO_PERMISSION");
			language.addLangString("COMMAND_WRONG_ARGS_LENGTH");
			language.addLangString("COMMAND_PLAYER_NOT_FOUND");
			language.addLangString("PERMISSIONS_GROUPS_LOADED");
			language.addLangString("PERMISSIONS_GROUPS_CHANGED");
			language.addLangString("PREMIUM_JOINED");
			language.addLangString("SERVER_FULL");
			language.addLangString("ARENA_COUNTDOWN");
			language.addLangString("ARENA_JOIN_ARENA");
			language.addLangString("ARENA_PLAYER_DEATH");
			language.addLangString("ARENA_PLAYER_LEAVE");

			// FastType Language String Registry

			language.addLangString("FastType_BB");
			language.addLangString("FastType_SRY");
			language.addLangString("FastType_GG");
			language.addLangString("FastType_GL");
			language.addLangString("FastType_WB");
			language.addLangString("FastType_KK");
			language.addLangString("FastType_KP");
			language.addLangString("FastType_KA");
			language.addLangString("FastType_NP");
			language.addLangString("FastType_PLS");
			language.addLangString("FastType_PLZ");
			language.addLangString("FastType_WTF");
			language.addLangString("FastType_OMG");
			language.addLangString("FastType_OMFG");
			language.addLangString("FastType_FU");
			language.addLangString("FastType_4U");
			language.addLangString("FastType_4EVER");
			language.addLangString("FastType_TY");
			language.addLangString("FastType_MOM");
			language.addLangString("FastType_THX");
			language.addLangString("FastType_ASAP");
			language.addLangString("FastType_AFAIK");
			language.addLangString("FastType_WTH");
			language.addLangString("FastType_WTFH");
			language.addLangString("FastType_IDK");
			language.addLangString("FastType_IDC");

			// ---------------------------------
			language.reloadLocale();

		} catch (Exception e) {
			this.getLogger()
					.severe("Ein schwerwiegender Error ist aufgetreten, während die Languagestrings von der MinigameAPI geaddet worden waren!");
		}
	}

	private void registerDefaultGroups() {
		permissions.addGroup(new Group("Spieler", "&2[Spieler]&r", "", 1));
		permissions.addGroup(new Group("Zocker", "&3[Zocker]&r", "", 2));
		permissions
				.addGroup(new Group("Alter-Hase", "&a[Alter-Hase]&r", "", 3));
		permissions.addGroup(new Group("VIP", "&1[Vip]&r", "", 4));
		permissions.addGroup(new Group("Gold-Vip", "&6[Gold-Vip]&r", "", 5));
		permissions.addGroup(new Group("Ultra-Vip", "&b[Ultra-Vip]&r", "", 6));
		permissions.addGroup(new Group("Moderator", "&e[Moderator]&r", "", 7));
		permissions.addGroup(new Group("Supporter", "&c[Supporter]&r", "", 8));
		permissions.addGroup(new Group("Admin", "&4[Admin]&r", "", 9));
		permissions.addGroup(new Group("Chef", "&9[Chef]&r", "", 10));
	}

	private void registerListeners() {
		Bukkit.getPluginManager().registerEvents(new PlayerJoinListener(),
				instance);
		Bukkit.getPluginManager().registerEvents(
				new PlayerChatFormatListener(), instance);
		Bukkit.getPluginManager().registerEvents(new ArenaListener(), instance);
	}

	private void registerAllCommands() {

		new BukkitRunnable() {
			@Override
			public void run() {
				try {

					commands.startLoader();
					commands.addCommand(new PermissionCommand("blackperm",
							"Blackbird-Permissions", "", "", Arrays
									.asList("bperm")));
				} catch (IllegalArgumentException | IllegalAccessException
						| NoSuchFieldException | SecurityException
						| ClassNotFoundException e) {
					instance.getLogger()
							.severe("Ein Fehler ist aufgetreten,während die Kommandos geladen worden waren");
				}

			}
		}.runTaskLater(instance, 20L);

	}

	private void registerFastTypes() {
		fast.addType("bb", "FastType_BB");
		fast.addType("sry", "FastType_SRY");
		fast.addType("gg", "FastType_GG");
		fast.addType("gl", "FastType_GL");
		fast.addType("wb", "FastType_WB");
		fast.addType("kk", "FastType_KK");
		fast.addType("kp", "FastType_KP");
		fast.addType("ka", "FastType_KA");
		fast.addType("np", "FastType_NP");
		fast.addType("pls", "FastType_PLS");
		fast.addType("plz", "FastType_PLZ");
		fast.addType("wtf", "FastType_WTF");
		fast.addType("omg", "FastType_OMG");
		fast.addType("omfg", "FastType_OMFG");
		fast.addType("fu", "FastType_FU");
		fast.addType("4u", "FastType_4U");
		fast.addType("4ever", "FastType_4EVER");
		fast.addType("ty", "FastType_TY");
		fast.addType("mom", "FastType_MOM");
		fast.addType("thx", "FastType_THX");
		fast.addType("asap", "FastType_ASAP");
		fast.addType("afaik", "FastType_AFAIK");
		fast.addType("wth", "FastType_WTH");
		fast.addType("wtfh", "FastType_WTFH");
		fast.addType("idk", "FastType_IDK");
		fast.addType("idc", "FastType_IDC");
	}

	public DatabaseAPI getDatabaseAPI() {
		return this.database;
	}

	public LanguageAPI getLanguageAPI() {
		return this.language;
	}

	public static MinigameAPI getInstance() {
		return instance;

	}

	public EconomyAPI getEconomyAPI() {
		return this.economy;
	}

	public CommandAPI getCommandAPI() {
		return commands;
	}

	public IngameShopAPI getIngameShopAPI() {
		return ingameShop;
	}

	public PermissionAPI getPermissionAPI() {
		return permissions;
	}

	public FastType getFastType() {
		return fast;
	}

	public GameState getGameState() {
		return state;
	}

	public void setGameState(GameState state) {
		if (state == null)
			return;
		this.state = state;
	}

	public void setArenaGameState(ArenaGameState state, Arena arena) {
		if (state == null || arena == null)
			return;
		gameStateMap.put(arena, state);
	}

	public ArenaGameState getArenaGameState(Arena arena) {
		return gameStateMap.get(arena);
	}

	public ArenaAPI getArenaAPI() {
		return arena;
	}

	public String getServerName() {
		return name;
	}
	public ScoreboardAPI getScoreboardAPI() {
		return scoreboard;
	}

}```