HX3 Foren

HX3 Foren (https://hx3.de/)
-   Editing & Scripting (https://hx3.de/editing-scripting-167/)
-   -   Variablenwert nach rejoin (https://hx3.de/editing-scripting-167/variablenwert-rejoin-21161/)

Troublemaker 25.11.2011 06:28

Variablenwert nach rejoin
 
Hallo,

gibt es eine Möglichkeit einen Variablenwert "am Server" zu speichern, damit dieser nach dem Rejoinen eines Clients wieder abgerufen werden kann?

Etwas genauer:
Ein Spieler bekommt für jeden Abschuß Geld (ähnlich wie bei Warfare). Dieser wird zb so gespeichert:
Code:

player setVariable["geld", (player getVariable "geld") + 100, true];
Die Player variablen sind doch aber nur auf dem Client gültig. Wenn der Spieler jetzt Verbindung verliert und rausfliegt, ist das Geld weg.
:sauer::motz:

Ich möchte aber, dass es wieder da ist sobald der gleiche Spieler wieder joint. Wenn's möglich ist, nicht wenn ein anderer Spieler im gleichen Slot, sondern schon derselbe menschliche player.

Habe auch schon versucht das als
Code:

missionNamespace setVariable [...]
zu erreichen, weil ich dachte, dass sich der Server dann merkt, solange die Mission läuft. Klappt aber auch nicht - wird auch lokal gespeichert!
:(

Weiß einer Rat?

Vienna 25.11.2011 10:26

Zitat:

Zitat von Troublemaker (Beitrag 395784)
Hallo,

gibt es eine Möglichkeit einen Variablenwert "am Server" zu speichern, damit dieser nach dem Rejoinen eines Clients wieder abgerufen werden kann?

Ja, gibt es. Aber es ist nicht einfach zu bewerkstelligen.

.....

Allgemeine Hinweise findest du hier: http://community.bistudio.com/wiki/6thSense.eu:EG


Edit: Eigentlich sollt das ja mit setVariable möglich sei. z.B. der gleiche Variablenname für alle Spieler, weil ja ans Objekt gebunden. Ob und wie das zu handhaben ist bzw. sicher funktioniert, weiß ich nicht.

Troublemaker 25.11.2011 10:28

Was für ein sympathischer Name... :daumen:
Atzgersdorf lässt grüßen! ;)

Ja, genau so etwas in dieser Richtung dachte ich mir schon. Irgendwie war ich etwas verwirrt, da die Vars, die mit
Code:

irgendwas setVariable ["blabla, 100, true];
gesetzt werden, ja nicht wirklich wie lokale Variablen aussehen. Also eben kein _irgendwas...
Außerdem sollte doch der dritte Arraywert (true) die Variable public machen... :rolleyes:

Naja, however, ich werde mir das mal durch den Kopf und Rechner gehen lassen und schrei nochmal, wenn's ned geht.

Erstmal aber daunkschee für den Tipp!

Troublemaker 25.11.2011 10:34

Ääääh... hab ich was mit den Augen, oder hast du dein Posting gekürzt?:komisch:

Irgendwie find ich deinen Vorschlag mit dem global und public machen nimmer...:motz:
Wollt mir das nochmal in Ruhe geben und jetzt ists weg! :oh:

Vienna 25.11.2011 10:40

Ich habe den Teil gelöscht, weil es eigentlich mit setVariable gehen sollte. Habe den Text noch im Zwischenspeicher, also hier nochmal. Ist mit Vorbehalt so zu programmieren.

Zitat:

Zitat von Troublemaker (Beitrag 395784)
Hallo,

gibt es eine Möglichkeit einen Variablenwert "am Server" zu speichern, damit dieser nach dem Rejoinen eines Clients wieder abgerufen werden kann?

Ja, gibt es. Aber es ist nicht einfach zu bewerkstelligen.

Solche "Konten" wären vom Server/Host zu verwalten. Was bei der Programmierung der Mission zu erfolgen hat.

Wenn ein Konto nur mit lokalen Variablen (das sind die mit beginnendem Unterstrich z.B. _Geld) in einem Skript gespeichert ist, dann ist der Kontostand nur auf dem jeweiligen PC und dort nur in diesem Skript bekannt. Wird ein Spieler aus der Mission geworfen oder stürzt das Skript ab, dann sind diese Daten verloren.

Solche Daten müssen in globalen Variablen ohne Unterstrich (z.B. Geld gespeichert werden. Damit sind sie nun auch außerhalb eines Skripts vorhanden.

Wird so eine globale Variable auf einem PC geändert, dann ist das ohne weitere Maßnahmen nur auf diesem PC bekannt. Soll also ein Server alle Konten verwalten, dann muss für eine Datenübertragung gesorgt werden.

Für eine Synchronisation dieser Variablen mit den Anderen PCs gibt es diese Befehle:
http://community.bistudio.com/wiki/a...leEventHandler
http://community.bistudio.com/wiki/publicVariable

Soll ein Server die Konten verwalten, dann geht es natürlich nicht mehr, wenn alle Spieler die Variable Geld verwenden. Für ein Konto benötigt dann jeder Spieler eine eigene Variable. Für nur wenige Spieler kann man diese Variablen schon vor dem Programmstart festlegen. Es ist aber auch möglich globale Variable erst während dem Programmlauf zu erstellen.

Wenn in einer Mission solche Konten nicht synchronisiert sind, dann liegt das an der sehr aufwendigen Programmierung.

Allgemeine Hinweise findest du hier: http://community.bistudio.com/wiki/6thSense.eu:EG


Edit: Eigentlich sollt das ja mit setVariable möglich sei. z.B. der gleiche Variablenname für alle Spieler, weil ja ans Objekt gebunden. Ob und wie das zu handhaben ist bzw. sicher funktioniert, weiß ich nicht.

Pfandgiraffe 25.11.2011 12:10

Das hat mit der normalen JIP Problematik nicht mehr soviel am Hut. Interessant für dich sind die Befehle onPlayerConnected und onPlayerDisconnected.

Beachte das beide Befehle nur vom Server ausgeführt werden dürfen (können)!
Außerdem benötigst du die UID des Spielers wenn du etwas Personenbezogen abfragen möchtest. Selbige wird bereits mit den beiden oben genannten Events übergeben.

Ob die Variable mit setVar, public oder was auch immer gesetzt wird spielt keine Rolle. Wichtig ist, dass die Variable bei disconnect des Spielers an den Server (mit onPlayerDisconnected) übergeben und zusammen mit seiner einzigartigen UID gehalten wird. Wenn ein Spieler connected muß (mit onPlayerConnected) gefragt werden ob dem Server die UID bereits bekannt ist und wenn ja wieder die dazugehörigen Variablen übergeben werden.


Falls du nicht allein auf die Lösung kommst, lasse ich dir eine per PM nach dem WE zukommen.


Gruß,
Psycho

Troublemaker 25.11.2011 14:35

Sehr cool. Werde mich damit mal rumspielen :daumen:

Da fallen mir ja dann wieder 100 Sachen ein, wenn das geht :D

Ah ja, onPlayerConnected habe ich mal überflogen, aber da ich das für JIP eigentlich nie gebraucht habe (mache das über einen Auslöser - funzt auch iwie besser), hab ich das wieder total vergessen... :rolleyes:

Vienna 25.11.2011 14:48

Logischerweise müssen dem Server die zu sichernden Daten laufend übermittelt werden, denn wenn ein Spieler disconnected kann er die ja nicht mehr übertragen.

So ist es wichtig wie die zu sichernden Variablen angelegt und übers Netzt aktualisiert werden. Mit setVariable sollte das einfacher sein, weil so eine Variable an das Objekt gebunden ist und die Variable für alle Spieler-Objekte den gleichen Namen haben kann. Das vereinfacht die Bearbeitung der Variablen in den Skripten erheblich.

Das alles für JIP korrekt lauffähig zu erstellen ist nicht einfach, weil man großteils mit Versuch und Irrtum vorgehen muss und das für MP umständlich zu testen ist. Als "Denkaufgabe" scheint mir das zu nervtötend.

Psychobastard, wenn du hier eine funktionierende Mission als Beispiel haben solltest, wäre das sicher von allgemeinem Interesse.

Pfandgiraffe 25.11.2011 14:55

Zitat:

Logischerweise müssen dem Server die zu sichernden Daten laufend übermittelt werden, denn wenn ein Spieler disconnected kann er die ja nicht mehr übertragen.
Das muß nicht - onPlayerDisconnected hilft dir dabei.

Zitat:

Psychobastard, wenn du hier eine funktionierende Mission als Beispiel haben solltest, wäre das sicher von allgemeinem Interesse.
Ich kann dir auch die Lösung schicken wenn du möchtest. :zahn:

Vienna 25.11.2011 15:16

Wenn ich das Spiel gewollt verlasse, dann kann ich mir vorstellen, dass die Variablen von meinem PC, die ja auch bei mir in der onPlayerDisconnecte-Routine vermerkt sind, noch schnell an der Server übertragen werden. Bei einem ungewollten Verbindungsabbruch wird das aber nicht mehr möglich sein.

Natürlich interessiert mich die Lösung, aber warum dass alles über PM und nicht hier im Thread?

Vienna 25.11.2011 17:33

Wenn ich mir bei Warfare diesen Eintrag in der Server-Initialisierung ansehe:
Code:

//--- JIP Handling.
onPlayerConnected    "[_uid,_name] ExecVM '...PlayerConnected.sqf'";
onPlayerDisconnected "[_uid,_name] ExecVM '...PlayerDisconnected.sqf'";

dann funktioniert das wie bei einem EventHandler. Was hier gespeichert und wieder hergestellt wird ist in den Skripten zu programmieren.

CptMike 26.11.2011 11:55

Hallo Troublemaker!

Ich weiß nicht genau ob dir das auch weiterhelfen könnte was die Jungs hier machen.
ArmA2 Persistent Database Scripts - WIP - Bohemia Interactive Forums

Vienna 26.11.2011 16:12

Liste der Anhänge anzeigen (Anzahl: 1)
Der Versuch einer Testmission:

In der Test-Mission gibt es drei spielbare Soldaten. Bei der Initialisierung werden die Variablen mit dem Objektnamen der Soldaten angesprochen, im Spiel dann jeweils nur noch mit Player (siehe im Code den Kommentar):
init.sqf
Code:

if (local player) then          //nur wenn Spieler
 {
    waitUntil {!isNull player}; //warten bis System Spieler initialisiert hat
 };

if (isServer) then            //nur für den Server/Host
 {
  onPlayerConnected    "[_uid,_name] ExecVM 'Server_PlayerConnected.sqf'";
  onPlayerDisconnected "[_uid,_name] ExecVM 'Server_PlayerDisconnected.sqf'";
 };

//Für Spieler und Server
S1 setVariable["geld", 0, false]; //mit false nicht public initialisieren!
S2 setVariable["geld", 0, false]; //mit false nicht public initialisieren!
S3 setVariable["geld", 0, false]; //mit false nicht public initialisieren!

//Im Spiel kann dann jeder Spieler seine Variable mit player ansprechen. z.B:
//
//  player setVariable["geld", (player getVariable "geld") + 100, true];
//
//true bedeutet hier, dass die Änderung zu den anderen PCs übertragen wird.

Nach einem Disconnect werden vom Server dem Spieler die aktuellen Variablenwerte übertragen. Das Connected-Skript wird auch beim Spielstart aufgerufen. Dabei könnte man die UID der Spieler, für einen späteren Vergleich, beim Server speichern:
Server_PlayerConnected.sqf
Code:

Private ["_uid","_name"];

_uid  = _this select 0;  //die einzigartige Spieler ID
_name = _this select 1;  //Name des Spielers

//Pause (bei Bedarf verlängern) damit die Init.sqs des Spieler die
//  folgenden Daten nicht überschreibt
sleep 1;

//Infoausgbe nur wenn Host der Server
 if (!isDedicated) then
  {
    player groupChat format ["Player Connected  UID: %1 | Name: %2",_uid,_name];
  };

//Aktuellen Spielstand übertragen
S1 setVariable["geld", S1 getVariable "geld", true];
S2 setVariable["geld", S2 getVariable "geld", true];
S3 setVariable["geld", S3 getVariable "geld", true];

Das Disconnected-Skrip wird hier nicht benötigt, da die Variablen bei jeder Änderung immer auch dem Server übermittelt werden (darum bei Daten-Änderung mit setVariable immer true einstellen!).
Server_PlayerDisconnected.sqf
Code:

Private ["_uid","_name"];

_uid  = _this select 0;  //die einzigartige Spieler ID
_name = _this select 1;  //Name des Spielers

Für das Testen sind in der der Beispielmission Funkbefehle vorhanden, mit denen die Werte der Variablen angezeigt und geändert werden können.

Für den Diskonnect-Test muss der Spieler wirklich das Spiel verlassen, nicht nur eine andere Spielfigur wählen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:37 Uhr.

Angetrieben durch vBulletin, Entwicklung von Philipp Dörner & Tobias


SEO by vBSEO 3.2.0 ©2008, Crawlability, Inc.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119