-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMyGameServer.java
149 lines (130 loc) · 5.8 KB
/
MyGameServer.java
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import ea.*;
/**
* @Description Server-Klasse eines Demo-Netzwerk-Spiels.
* Bevor keine Server-Instanz erzeugt wurde, kann sich kein Spieler anmelden!
* Der Server kann auf einem beliebigen Rechner (auch auf einem Client-Rechner) gestartet werden.
* Anschliessend verbinden sich die beiden Clients mit dem Server.
* Die Clients senden jede gewuenschte Zustands-Aenderung erst an den Server.
* Dieser sendet daraufhin als Reaktion an beide Clients "Befehle" zur Aenderung
* des lokalen Spiel-Zustands.
*
* @Author Mike Ganshorn
*
* @Version 1.1 (2015-02-18)
*
*/
class MyGameServer
// Ein Server lauscht nur auf Verbindungs-Anfragen. Zum Antworten auf eine Anfrage hat er bereits
// das SenderInterface implementiert, welches ihm die Methode senden(...) verschafft.
// Um auch auf weitere Sendungen von den Clients ( nach der Anmeldung) reagieren zu koennen,
// musst du noch das Interface Empfaenger implementieren, das die Methoden empfange...(...) verschafft
implements ea.Empfaenger
{
private String[] spieler;
private int akt_spieler;
private ea.Server server;
/**
* Konstruktor der Klasse MyGameServer. <br />
*
* Muss auf einem beliebigen Rechner gestartet werden, bevor sich Clients anmelden koennen.
*
* @param port Der Port auf dem der Server lauschen soll.
*/
public MyGameServer( int port )
{
server = new ea.Server( port );
this.spieler = new String[2]; // Bei unbekannter Client-Zahl ist eine java.util.ArrayList besser geeignet
this.akt_spieler = 0;
// Dieses MyServer-Objekt benachrichtigen, wenn der Server eine Nachricht empfaengt.
// Wegen Implementation des Interfaces ist unser MyGameServer auch Empfaenger fuer Netzwerk-Kommunikation
server.globalenEmpfaengerSetzen( this );
}
/**
* Vom Interface Empfaenger vorgeschriebene Methode zum Empfangen eines Strings von der Netzwerk-Gegenstelle.
* Diese Methode wird auftomatisch aufgerufen, sobald von der Netzwerk-Gegenstelle ein String lokal ankommt.
* <br />
*
* Hier wird ein sehr primitives Protokoll mit nur 3 "Befehlen" verwendet:
* anmelden, bewegen, farbwechsel <br />
*
* Jeder Client sendet jeden Aenderungs-Wunsch erst an den Server und dieser sendet
* danach als Reaktion an beide (alle) Clients den entsprechenden "Befehl" zur Aenderung
* des lokalen Spiel-Zustands.
*
* @param s Der empfangene Text ("Befehl" vom Server - definiert im Protokoll)
*/
@Override
public void empfangeString( String s )
{
// Das Protokoll besteht aus folgender Logik:
// Jeder Befehl besteht aus mehreren Teilen, die mit Doppelpunkt getrennt als ein String gesendet werden.
// Empfangenen Befehl in seine Bestandteile auftennen - Doppelpunkte werden dabei entfernt
String[] befehlBestandteile = s.split( ":" );
// Die Fallunterscheidung realisiert die Umsetzung des Protokolls:
// Struktur des 1. Befehls: anmelden:name
if ( befehlBestandteile[0].equals("anmelden") ) {
// erst auf beide Spieler warten
if ( this.akt_spieler < this.spieler.length ) {
this.spieler[this.akt_spieler] = befehlBestandteile[1];
this.akt_spieler++;
}
// danach bei den Clients das Spiel starten
if ( this.akt_spieler == this.spieler.length ) {
// Das Protokoll sieht folgende Struktur vor: neu:name:index:x:y
// Ein "Befehl" dieser Stuktur muss an die Clients gesendet werden
int x;
int y;
// Zufaelligen Ort fuer Spieler 1 bestimmen
x = (int)((Math.random()) * 700 + 50);
y = (int)((Math.random()) * 500 + 50);
server.sendeString("neu:" + this.spieler[0] + ":0:" + x + ":" + y);
// Zufaelligen Ort fuer Spieler 2 bestimmen
x = (int)((Math.random()) * 700 + 50);
y = (int)((Math.random()) * 500 + 50);
server.sendeString("neu:" + this.spieler[1] + ":1:" + x + ":" + y);
}
}
// Struktur des 2. Befehls: bewegen:index:dx:dy
else if ( befehlBestandteile[0].equals("bewegen") ) {
// Wunsch auf Zustands-Aenderung an beide (alle) Clients weiter leiten
server.sendeString(s);
}
// farbwechsel:index:farbe
else if ( befehlBestandteile[0].equals("farbwechsel") ) {
// Wunsch auf Zustands-Aenderung an beide (alle) Clients weiter leiten
server.sendeString(s);
}
}
// Info: Diese Methoden werden vom Interface Empfaenger gefordert. Sie muessen implementiert werden.
// Ihre Ruempfe bleiben leer, da diese Methoden in der Demo nicht verwendet werden.
@Override
public void empfangeInt (int i)
{
// Diese Methode wird in dieser Demo nicht aufgerufen
}
@Override
public void empfangeByte (byte b)
{
// Diese Methode wird in dieser Demo nicht aufgerufen
}
@Override
public void empfangeDouble (double d)
{
// Diese Methode wird in dieser Demo nicht aufgerufen
}
@Override
public void empfangeChar (char c)
{
// Diese Methode wird in dieser Demo nicht aufgerufen
}
@Override
public void empfangeBoolean (boolean b)
{
// Diese Methode wird in dieser Demo nicht aufgerufen
}
@Override
public void verbindungBeendet ()
{
// Diese Methode wird in dieser Demo nicht aufgerufen
}
}