Crossfire JXClient, Trunk
MetaserverProcessor.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-2017,2019-2023 Andreas Kirschbaum
20  * Copyright (C) 2010-2012,2014-2018,2020-2023 Nicolas Weeger
21  */
22 
23 package com.realtime.crossfire.jxclient.metaserver;
24 
28 import java.nio.file.Path;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Map;
32 import org.jetbrains.annotations.NotNull;
33 import org.jetbrains.annotations.Nullable;
34 
42 public class MetaserverProcessor {
43 
47  private static final int UPDATE_INTERVAL = 15*60;
48 
52  private static final int MIN_UPDATE_INTERVAL = 5*60;
53 
57  private static final long EXPIRE_INTERVAL = 60L*60*24*2;
58 
62  @NotNull
63  private final Collection<Metaserver> metaservers = new ArrayList<>();
64 
68  @NotNull
70 
74  @NotNull
75  private final ServerCache serverCache;
76 
80  @NotNull
81  private final Object sync = new Object();
82 
86  @Nullable
87  private Thread thread;
88 
92  private boolean enabled;
93 
97  private long nextQuery = System.currentTimeMillis();
98 
103 
107  @NotNull
108  private final Runnable runnable = new Runnable() {
109 
110  @Override
111  public void run() {
112  try {
113  while (!Thread.currentThread().isInterrupted()) {
114  synchronized (sync) {
115  if (enabled) {
116  final long now = System.currentTimeMillis();
117  final long delay = Math.max(nextQuery, lastQuery+MIN_UPDATE_INTERVAL*1000)-now;
118  if (delay > 0) {
119  sync.wait(delay);
120  } else {
121  nextQuery = now+UPDATE_INTERVAL*1000;
122  lastQuery = now;
123  for (final Metaserver metaserver : metaservers) {
124  updateMetaList(metaserver);
125  }
126  }
127  } else {
128  //noinspection WaitOrAwaitWithoutTimeout
129  sync.wait();
130  }
131  }
132  }
133  } catch (final InterruptedException ignored) {
134  // ignore
135  }
136  }
137 
138  };
139 
144  @NotNull
145  @SuppressWarnings("FieldCanBeLocal")
147 
148  @Override
149  public void start() {
150  // ignore
151  }
152 
153  @Override
154  public void metaserver() {
155  enable();
156  }
157 
158  @Override
159  public void preConnecting(@NotNull final String serverInfo) {
160  // ignore
161  }
162 
163  @Override
164  public void connecting(@NotNull final String serverInfo) {
165  disable();
166  }
167 
168  @Override
169  public void connecting(@NotNull final ClientSocketState clientSocketState, @NotNull final String param) {
170  // ignore
171  }
172 
173  @Override
174  public void connected() {
175  // ignore
176  }
177 
178  @Override
179  public void connectFailed(@NotNull final String reason) {
180  // ignore
181  }
182 
183  };
184 
192  public MetaserverProcessor(@NotNull final GuiStateManager guiStateManager, @Nullable final Path metaserverCacheFile, @NotNull final MetaserverModel metaserverModel) {
193  this.metaserverModel = metaserverModel;
194  serverCache = new ServerCache(metaserverCacheFile);
195  guiStateManager.addGuiStateListener(guiStateListener);
197  serverCache.getAll().values().forEach(metaserverModel::addMetaserverEntry);
199  }
200 
205  public void addMetaserver(@NotNull final Metaserver metaserver) {
206  synchronized (sync) {
207  metaservers.add(metaserver);
208  }
209  }
210 
214  public void start() {
215  synchronized (sync) {
216  if (thread == null) {
217  thread = new Thread(runnable, "JXClient:MetaserverProcessor");
218  thread.setDaemon(true);
219  thread.start();
220  }
221  nextQuery = System.currentTimeMillis();
222  sync.notifyAll();
223  }
224  }
225 
229  public void stop() {
230  synchronized (sync) {
231  if (thread != null) {
232  try {
233  thread.interrupt();
234  sync.notifyAll();
235  try {
236  thread.join(5000);
237  } catch (final InterruptedException ex) {
238  //noinspection UseOfSystemOutOrSystemErr
239  System.err.println("Cannot stop metaserver thread: "+ex);
240  }
241  } finally {
242  thread = null;
243  }
244  }
245  }
246  }
247 
251  private void disable() {
252  synchronized (sync) {
253  enabled = false;
254  sync.notifyAll();
255  }
256  }
257 
261  private void enable() {
262  synchronized (sync) {
263  enabled = true;
264  nextQuery = System.currentTimeMillis();
265  sync.notifyAll();
266  }
267  }
268 
273  private void updateMetaList(@NotNull final Metaserver metaserver) {
275 
277  final Map<String, MetaserverEntry> oldEntries = serverCache.getAll();
278 
279  for (final MetaserverEntry metaserverEntry : metaserver.queryMetaserver()) {
280  metaserverModel.addMetaserverEntry(metaserverEntry);
281  oldEntries.remove(metaserverEntry.getKey());
282  serverCache.put(metaserverEntry);
283  }
284 
285  // add previously known entries that are not anymore present
286  oldEntries.values().forEach(metaserverModel::addMetaserverEntry);
287 
289  serverCache.save();
290  }
291 
292 }
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.sync
final Object sync
Definition: MetaserverProcessor.java:81
com.realtime.crossfire.jxclient
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.serverCache
final ServerCache serverCache
Definition: MetaserverProcessor.java:75
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.runnable
final Runnable runnable
Definition: MetaserverProcessor.java:108
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.EXPIRE_INTERVAL
static final long EXPIRE_INTERVAL
Definition: MetaserverProcessor.java:57
com.realtime.crossfire.jxclient.metaserver.ServerCache.put
void put(@NotNull final MetaserverEntry metaserverEntry)
Definition: ServerCache.java:79
com.realtime.crossfire.jxclient.guistate.ClientSocketState
Definition: ClientSocketState.java:30
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.updateMetaList
void updateMetaList(@NotNull final Metaserver metaserver)
Definition: MetaserverProcessor.java:273
com.realtime.crossfire.jxclient.metaserver.Metaserver
Definition: Metaserver.java:32
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.MetaserverProcessor
MetaserverProcessor(@NotNull final GuiStateManager guiStateManager, @Nullable final Path metaserverCacheFile, @NotNull final MetaserverModel metaserverModel)
Definition: MetaserverProcessor.java:192
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.lastQuery
long lastQuery
Definition: MetaserverProcessor.java:102
com.realtime.crossfire.jxclient.guistate.GuiStateManager
Definition: GuiStateManager.java:34
com.realtime.crossfire.jxclient.metaserver.ServerCache.expire
void expire(final long timestamp)
Definition: ServerCache.java:87
com.realtime.crossfire.jxclient.guistate
Definition: ClientSocketState.java:23
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.stop
void stop()
Definition: MetaserverProcessor.java:229
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.guiStateListener
final GuiStateListener guiStateListener
Definition: MetaserverProcessor.java:146
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.metaserverModel
final MetaserverModel metaserverModel
Definition: MetaserverProcessor.java:69
com.realtime.crossfire.jxclient.guistate.GuiStateListener
Definition: GuiStateListener.java:32
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.start
void start()
Definition: MetaserverProcessor.java:214
com.realtime.crossfire.jxclient.metaserver.MetaserverModel.commit
void commit()
Definition: MetaserverModel.java:140
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.addMetaserver
void addMetaserver(@NotNull final Metaserver metaserver)
Definition: MetaserverProcessor.java:205
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.metaservers
final Collection< Metaserver > metaservers
Definition: MetaserverProcessor.java:63
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.enable
void enable()
Definition: MetaserverProcessor.java:261
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.thread
Thread thread
Definition: MetaserverProcessor.java:87
com.realtime.crossfire
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.UPDATE_INTERVAL
static final int UPDATE_INTERVAL
Definition: MetaserverProcessor.java:47
com.realtime.crossfire.jxclient.metaserver.ServerCache.save
void save()
Definition: ServerCache.java:174
com.realtime
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor
Definition: MetaserverProcessor.java:42
com
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.MIN_UPDATE_INTERVAL
static final int MIN_UPDATE_INTERVAL
Definition: MetaserverProcessor.java:52
com.realtime.crossfire.jxclient.metaserver.MetaserverModel.addMetaserverEntry
void addMetaserverEntry(@NotNull final MetaserverEntry metaserverEntry)
Definition: MetaserverModel.java:124
com.realtime.crossfire.jxclient.metaserver.MetaserverModel.begin
void begin()
Definition: MetaserverModel.java:133
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.disable
void disable()
Definition: MetaserverProcessor.java:251
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.nextQuery
long nextQuery
Definition: MetaserverProcessor.java:97
com.realtime.crossfire.jxclient.metaserver.MetaserverProcessor.enabled
boolean enabled
Definition: MetaserverProcessor.java:92
com.realtime.crossfire.jxclient.metaserver.ServerCache.getAll
Map< String, MetaserverEntry > getAll()
Definition: ServerCache.java:98
com.realtime.crossfire.jxclient.metaserver.MetaserverEntry
Definition: MetaserverEntry.java:33
com.realtime.crossfire.jxclient.metaserver.MetaserverModel
Definition: MetaserverModel.java:40
com.realtime.crossfire.jxclient.metaserver.ServerCache
Definition: ServerCache.java:43