Crossfire JXClient, Trunk  R20561
NumLookObjects.java
Go to the documentation of this file.
1 /*
2  * This file is part of JXClient, the Fullscreen Java Crossfire Client.
3  *
4  * JXClient is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * JXClient is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with JXClient; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  * Copyright (C) 2005-2008 Yann Chachkoff.
19  * Copyright (C) 2006-2011 Andreas Kirschbaum.
20  */
21 
22 package com.realtime.crossfire.jxclient.server.crossfire;
23 
27 import org.jetbrains.annotations.NotNull;
28 import org.jetbrains.annotations.Nullable;
29 
34 public class NumLookObjects {
35 
40  private static final int DEFAULT_NUM_LOOK_OBJECTS = 50;
41 
45  @NotNull
47 
52  @Nullable
53  private final DebugWriter debugProtocol;
54 
58  @NotNull
59  private final Object sync = new Object();
60 
65  private boolean connected;
66 
71 
76  private int pendingNumLookObjects;
77 
81  private int currentNumLookObjects;
82 
86  private boolean pending;
87 
95  NumLookObjects(@NotNull final CrossfireServerConnection crossfireServerConnection, @Nullable final DebugWriter debugProtocol) {
96  this.crossfireServerConnection = crossfireServerConnection;
97  this.debugProtocol = debugProtocol;
98  }
99 
103  public void connected() {
104  synchronized (sync) {
105  connected = false;
106  pendingNumLookObjects = 0;
107  if (debugProtocol != null) {
108  debugProtocol.debugProtocolWrite("connected: defaulting to pending_num_look_objects="+pendingNumLookObjects);
109  }
110  currentNumLookObjects = DEFAULT_NUM_LOOK_OBJECTS;
111  if (debugProtocol != null) {
112  debugProtocol.debugProtocolWrite("connected: defaulting to num_look_objects="+currentNumLookObjects);
113  }
114  sync.notifyAll();
115  }
116  }
117 
121  private void negotiateNumLookObjects() {
122  final int numLookObjects;
123  synchronized (sync) {
124  pending = false;
125  numLookObjects = preferredNumLookObjects;
126  if (debugProtocol != null) {
127  debugProtocol.debugProtocolWrite("negotiateNumLookObjects: "+numLookObjects);
128  }
129 
130  if (!connected) {
131  if (debugProtocol != null) {
132  debugProtocol.debugProtocolWrite("negotiateNumLookObjects: not connected, ignoring");
133  }
134  return;
135  }
136  if (pendingNumLookObjects != 0) {
137  if (debugProtocol != null) {
138  debugProtocol.debugProtocolWrite("negotiateNumLookObjects: already negotiating pending_num_look_objects="+pendingNumLookObjects+", ignoring");
139  }
140  return;
141  }
142  if (currentNumLookObjects == numLookObjects) {
143  if (debugProtocol != null) {
144  debugProtocol.debugProtocolWrite("negotiateNumLookObjects: unchanged from num_look_objects="+currentNumLookObjects+", ignoring");
145  }
146  return;
147  }
148  pendingNumLookObjects = numLookObjects;
149  if (debugProtocol != null) {
150  debugProtocol.debugProtocolWrite("negotiateNumLookObjects: pending_num_look_objects="+pendingNumLookObjects+", sending setup command");
151  }
152  sync.notifyAll();
153  }
154  crossfireServerConnection.sendSetup("num_look_objects "+numLookObjects);
155  }
156 
163  public void processSetupNumLookObjects(@NotNull final String value) throws UnknownCommandException {
164  if (value.equals("FALSE")) {
165  System.err.println("Warning: the server is too old for this client since it does not support the num_look_objects setup option.");
166  System.err.println("Expect issues with the ground view display.");
167  synchronized (sync) {
168  pendingNumLookObjects = 0;
169  sync.notifyAll();
170  }
171  if (debugProtocol != null) {
172  debugProtocol.debugProtocolWrite("processSetup: pending_num_look_objects=0 [server didn't understand setup command]");
173  }
174  } else {
175  final int thisNumLookObjects;
176  try {
177  thisNumLookObjects = Integer.parseInt(value);
178  } catch (final NumberFormatException ignored) {
179  throw new UnknownCommandException("the server returned 'setup num_look_objects "+value+"'.");
180  }
181  final boolean negotiate;
182  synchronized (sync) {
183  if (pendingNumLookObjects == 0) {
184  System.err.println("the server sent an unexpected 'setup num_look_objects "+value+"'.");
185  negotiate = false;
186  } else {
187  if (pendingNumLookObjects != thisNumLookObjects) {
188  System.err.println("Warning: the server didn't accept the num_look_objects setup option: requested "+pendingNumLookObjects+", returned "+thisNumLookObjects+".");
189  System.err.println("Expect issues with the ground view display.");
190  }
191  pendingNumLookObjects = 0;
192  if (debugProtocol != null) {
193  debugProtocol.debugProtocolWrite("processSetup: pending_num_look_objects="+pendingNumLookObjects+" [ok]");
194  }
195  currentNumLookObjects = thisNumLookObjects;
196  if (debugProtocol != null) {
197  debugProtocol.debugProtocolWrite("processSetup: num_look_objects="+currentNumLookObjects);
198  }
199  negotiate = currentNumLookObjects != preferredNumLookObjects;
200  if (negotiate) {
201  pending = true;
202  }
203  sync.notifyAll();
204  }
205  }
206  if (negotiate) {
208  }
209  }
210  }
211 
216  public void setPreferredNumLookObjects(final int preferredNumLookObjects) {
217  synchronized (sync) {
218  final int preferredNumLookObjects2 = Math.max(3, preferredNumLookObjects);
219  if (this.preferredNumLookObjects == preferredNumLookObjects2) {
220  return;
221  }
222 
223  this.preferredNumLookObjects = preferredNumLookObjects2;
224  pending = true;
225  }
227  }
228 
234  synchronized (sync) {
235  return currentNumLookObjects;
236  }
237  }
238 
245  public void waitForCurrentNumLookObjectsValid() throws InterruptedException {
246  synchronized (sync) {
247  while (!connected || pendingNumLookObjects != 0 || pending) {
248  sync.wait();
249  }
250  }
251  }
252 
257  public void setClientSocketState(@NotNull final ClientSocketState clientSocketState) {
258  synchronized (sync) {
259  connected = clientSocketState == ClientSocketState.CONNECTED;
260  sync.notifyAll();
261  if (!connected) {
262  return;
263  }
264  pending = true;
265  }
267  }
268 
269 }
void negotiateNumLookObjects()
Requests a change of the number of ground objects from the server.
static final int DEFAULT_NUM_LOOK_OBJECTS
The default number of ground objects when no "setup num_look_objects" command has been sent...
void processSetupNumLookObjects(@NotNull final String value)
Called when a "setup num_look_objects" response has been received from the server.
void connected()
Called after the server connection has been established.
boolean pending
Whether negotiation may be pending.
final DebugWriter debugProtocol
The appender to write protocol commands to.
final Object sync
The synchronization objects for accessing mutable fields.
void debugProtocolWrite(@NotNull final CharSequence str)
Writes a message to the debug protocol.
int currentNumLookObjects
The currently active number of ground view objects.
Writer debug information to a log file.
int preferredNumLookObjects
The number of ground view objects to be negotiated with the server.
boolean connected
Whether the current client socket state is ClientSocketState#CONNECTED.
void setPreferredNumLookObjects(final int preferredNumLookObjects)
Sets the preferred number of ground items.
int getCurrentNumLookObjects()
Returns the current number of ground items.
An UnknownCommandException is generated whenever an unknown message packet is received from the serve...
void waitForCurrentNumLookObjectsValid()
Waits until getCurrentNumLookObjects() is stable.
final CrossfireServerConnection crossfireServerConnection
The CrossfireServerConnection for sending "setup" commands.
Adds encoding/decoding of crossfire protocol packets to a ServerConnection.
void sendSetup(@NotNull String... options)
Sends a "setup" command to the server.
int pendingNumLookObjects
The number of ground view objects being negotiated with the server.
void setClientSocketState(@NotNull final ClientSocketState clientSocketState)
Called whenever the client socket state has changed.
Negotiates the size of the ground view in items with the Crossfire server.
Connection progress states of the Crossfire server connection.