Prüfen ob Koordinaten belegt


lordkimahri

Grünschnabel
Für meinen Minecraftserver möchte ich ein UserControlPanel entwickeln. Hierbei soll der Spieler die Möglichkeit haben seine Gebiete selbst zu schützen.

Jedoch will ich vorher überprüfen ob der Bereich schon von einem anderem Spieler geschützt ist.

Die formatierung der Datenbank wird von einem Plugin vorgegeben und ist nicht änderbar, hier ein Screenshot:

coords.png
Die Y-Koordinate muss hierbei nicht geprüft werden.

Wie wäre der beste ansatz um die Koordinaten X und Z prüfen zu lassen?

Die möglichkeit mit range() und in_array() erscheint mir zwar schlüssig aber ist es ratsam die bei eventuell mehr als 100 einträgen in einer schleife laufen zu lassen? Oder ist das vllt sogar der einzige weg?
 
Zuletzt bearbeitet:

lordkimahri

Grünschnabel
Mit SQL und between?
Mein gedanke war die Anfragen der User in einen Quee (eine MySQL-Db) schreiben.
Wenn jetzt der Quee abgearbeitet wird, soll Überprüft werden ob die Koordinaten noch frei sind.

Hierfür hole ich jeden eintrag einzeln aus dem Quee, und lasse ihn mittels range() beide Koordinaten (X und Z)
in ein array packen. Nun lasse ich alle geschützten bereiche aus der Datenbank (siehe Foto) laden, mit range() in arrays auflösen und möchte beide arrays für die Koordinaten mittels schleife mit inArray() prüfen ob ein oder mehrere Felder in der anfrage schon belegt sind.

Gibt es hierfür einen Performanteren weg?

Das MySQL between unterstützt ist mir klar, funktioniert dies auch mit Negativen werten?
Und ist es möglich zu sagen das der Eintrag in die Zieldatenbank nur erfolgt wenn bei der Prüfung beider Koordinaten keines der Felder schon belegt ist?
 
Zuletzt bearbeitet:

Yaslaw

n/a
Moderator
Also. Ich kenne mich mit dem Mindcraftszeug nicht aus. Diene Erklärung mit Array und Array und Array helfen mir da nicht. Das iwrd auf alle Fälle komplex und unübersichtlich.

Du willst testen ob die Koordinate X uns Z bereits in der DB vergeben sind. Dort hast du Ranges mit min und max. Alles dazwischen ist vergeben.

Ja, SQL-Between kann mit negativen Angaben arbeiten.
SQL:
-- Gesuchte X: -250, Z: 150
-- Wenn count(*) > 0 dann ist es bereits belegt
$select count(*)
from my_table
where -250 between min_x and max_x
    and 150 between min_z and max_z
 

lordkimahri

Grünschnabel
Ok, ich denke das deine Lösung um einiges Performanter ist. Dann werde ich es auf diese Weise mal versuchen.

Würde die Abfrage so wie von dir als Beispiel denn Funktionieren?

Frage wegen count(*), habe damit noch nicht gearbeitet! Und vorallem muss ich ja eigentlich Between doppelt nutzen.

Denn die Daten aus dem Quee haben ja auch eine Start und Endkoordinate!
 

Yaslaw

n/a
Moderator
SQL:
SELECT
    count(p1.*)
FROM
    my_table AS p1,
    -- Hier mal die Testdaten
    (select -230 as min_x, -130 as max_x, 120 as min_z, 150 as max_z) AS p2
WHERE
    LEAST(p2.max_x, p1.max_x) >= GREATEST(p2.min_x, p1.min_x)
    or LEAST(p2.max_z, p1.max_z) >= GREATEST(p2.min_z, p1.min_z)
 

lordkimahri

Grünschnabel
Den Quee habe ich noch nicht, das war der Ablauf den ich mir vorgestellt habe. Die Datenbank würde aber identisch zu der auf dem Bild sein.

Könntest du mir den Query mal näher erläutern? Ich kann dem Query nicht zu 100% folgen.
 

Yaslaw

n/a
Moderator
Der innere Select sind die Testdaten. Das müsste dann deine Quee sein.
LEAST() und GREATEST() findest du in der MySQL-Doku

LEAST(p2.max_x, p1.max_x) >= GREATEST(p2.min_x, p1.min_x)
Nimm das kleinere Maximum und schaue, ob es grösser ist als das Grösste Minimum. Wenn ja, haben wir eine Bereichsüberschneidung. Das macht man mit X und mit Z. Wenn eines von beidem eine Überschneidung hat, dann sind die Koordinaten schon besetzt.
Oder müssten beide eine Überschneidung haben? Dann wäre es AND anstelle von OR. Aber das ergibt sich mir grad nicht, da ich von der Materie keine Ahnung habe

Wenn Count(*) 0 zurückgibt, ist der Bereich noch frei.
 

lordkimahri

Grünschnabel
Theoretisch müsste es glaube ich AND sein. Aber das kann man ja auch austesten. Danke erstmal für die Hilfe.
Sollte ich noch Fragen haben melde ich mich wieder^^
 

lordkimahri

Grünschnabel
Eine Frage stellt sich mir noch. Wie vergleiche ich jetzt jeden Eintrag im quee einzeln mit jedem Eintrag in der Datenbank der schon bestehenden Bereiche? Hierfür kommt nur eine for schleife in betracht oder?
 

lordkimahri

Grünschnabel
Habe jetzt nochmal genau darüber nachgedacht.

Ich muss überprüfen ob die Kombination aus X und Z koordinate schon belegt ist.


Was den Quee angeht soll dieser folgendermaßen aufgebaut sein:

| ID | Spieler | min-X | min- Y | min-Z | max-X | max-Y | max-Z | timestamp |
 

Yaslaw

n/a
Moderator
Ja, das habe ich ja bereits mit SQL gelöst.
Was willst du mit deiner Schleife durchgehen?
Das ist ein Quee-Eintrag., nicht die Quee
ALso nochmals.
Wie sind diese "Wie vergleiche ich jetzt jeden Eintrag im quee einzeln" gespeichert?
Es gibt viele Arten von Listen:

Eine Datenbanktabelle mit Einträgen? Ein Array? Ein Objekt?
Woher hast du diese Quee?

Falls es eine DB-Tabelle ist, dann kannst du mit einer SQL-Abfrage alles Abhandeln. Ist es ein Array oder Objekt, dann hilft dir ein Iterator.
 

lordkimahri

Grünschnabel
Ich möchte die Datenbankeinträge des quees mit der Datenbank in der die belegten koordinaten sind abgleichen. Allerdings muss ich das Ergebnis (frei oder belegt) mit dem Spielernamen und den koordinaten an eine php-datei weiterleiten, um so einen Befehl auf dem Minecraft-Server ausführen zu können.
 

Yaslaw

n/a
Moderator
Ah, quee ist eine DB-Tabelle. Das macht die Welt so einfach
SQL:
-- Namen müssen angepasst werden
SELECT
    q.id,
    q.spieler,
    0 = (
        select count(p1.*)
        FROM
            my_table AS p1,
            tbl_quee AS q1
        WHERE
            q1.id = q.id
            AND ( 
                LEAST(q1.max_x, p1.max_x) >= GREATEST(q1.min_x, p1.min_x)
                OR LEAST(q1.max_z, p1.max_z) >= GREATEST(q1.min_z, p1.min_z)
            )
    ) as is_free
FROM tbl_quee
Das kann dann im PHP angezeigt werden
 

lordkimahri

Grünschnabel
Hier ein kleines Bildchen wie ich mir den Aufbau Gedacht habe:

schaubild.png
Ich möchte den Direkten zugriff auf die PHP-Api die mit dem MC-Server verbunden ist auf diese Art vermeiden. Um den Missbrauch der Api zu verhindern.

Damit der Quee Regelmäßig überprüft und geleert wird dachte ich an ein Cronjob der eine bestimmte Php-Datei in regelmäßigen abständen öffnet und somit die Überprüfung durchführt.
 

Yaslaw

n/a
Moderator
Ja. Und die Überprüfung kannst du ja locker vom PHP aus in der DB machen. Siehe mein letztes SQL.
Das kannst du dann in der PHP-Api auswerten.
 

lordkimahri

Grünschnabel
Dein Beispiel trägt ja nur die Daten in den Quee ein die noch nicht belegt sind wenn ich das richtig sehe.
Ich wäre am überlegen ob man dem Quee dann nicht noch eine Spalte hinzufügt, beispielsweise | isfree | die mit true und false angibt ob koordinaten frei oder belegt sind.

So könnte ich dann im Cronjob mit der spalte isfree den passenden Befehl über die Php-Api an den Server senden lassen.

Nur wie müsste ich dafür dein Code modifizieren?