Crossfire JXClient, Trunk
PoisonWatcher.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.stats;
24 
27 import java.awt.event.ActionListener;
28 import javax.swing.Timer;
29 import org.jetbrains.annotations.NotNull;
30 
36 public class PoisonWatcher {
37 
42  private static final int TIMEOUT_DE_ASSERT = 10000;
43 
47  @NotNull
48  private static final String ASSERT_MESSAGE = "You feel very sick...";
49 
53  @NotNull
54  private static final String DE_ASSERT_MESSAGE = "You feel much better now.";
55 
59  @NotNull
60  private static final String CURE_MESSAGE = "Your body feels cleansed";
61 
65  @NotNull
66  private final Object sync = new Object();
67 
71  @NotNull
72  private final Stats stats;
73 
77  private boolean active = true;
78 
82  private boolean serverSupportsPoisonedFlag;
83 
87  @NotNull
88  @SuppressWarnings("FieldCanBeLocal")
90 
91  @Override
92  public void commandDrawextinfoReceived(final int color, final int type, final int subtype, @NotNull final String message) {
93  check(message);
94  }
95 
96  @Override
97  public void setDebugMode(final boolean printMessageTypes) {
98  // ignore
99  }
100 
101  };
102 
106  @NotNull
107  @SuppressWarnings("FieldCanBeLocal")
108  private final StatsListener statsListener = new StatsListener() {
109 
110  @Override
111  public void resetBefore() {
112  }
113 
114  @Override
115  public void resetAfter() {
116  synchronized (sync) {
118  }
119  }
120 
121  @Override
122  public void statChanged(final int statNo, final int value) {
123  if (statNo == Stats.CS_STAT_CHARACTER_FLAGS) {
124  synchronized (sync) {
126  setActive((value&Stats.CF_POISONED) != 0);
127  }
128  }
129  }
130 
131  @Override
132  public void simpleWeaponSpeedChanged(final boolean simpleWeaponSpeed) {
133  }
134 
135  @Override
136  public void titleChanged(@NotNull final String title) {
137  }
138 
139  @Override
140  public void godNameChanged(@NotNull final String godName) {
141  }
142 
143  @Override
144  public void rangeChanged(@NotNull final String range) {
145  }
146 
147  @Override
148  public void activeSkillChanged(@NotNull final String activeSkill) {
149  }
150 
151  @Override
152  public void experienceChanged(final long exp) {
153  }
154 
155  @Override
156  public void experienceNextLevelChanged(final long expNextLevel) {
157  }
158 
159  };
160 
165  @NotNull
166  private final ActionListener timeoutEvent = e -> {
167  synchronized (sync) {
169  setActive(false);
170  }
171  }
172  };
173 
177  @NotNull
178  private final Timer timer = new Timer(TIMEOUT_DE_ASSERT, timeoutEvent);
179 
185  public PoisonWatcher(@NotNull final Stats stats, @NotNull final CrossfireServerConnection crossfireServerConnection) {
186  this.stats = stats;
187  timer.setRepeats(false);
188  crossfireServerConnection.addCrossfireDrawinfoListener((text, type) -> check(text));
189  crossfireServerConnection.addCrossfireDrawextinfoListener(drawextinfoListener);
191  synchronized (sync) {
192  setActive(false);
193  }
194  }
195 
200  private void check(@NotNull final String message) {
201  synchronized (sync) {
203  if (message.equals(ASSERT_MESSAGE)) {
204  setActive(true);
205  } else if (message.equals(DE_ASSERT_MESSAGE) || message.equals(CURE_MESSAGE)) {
206  setActive(false);
207  }
208  }
209  }
210  }
211 
216  private void setActive(final boolean active) {
217  if (!Thread.holdsLock(sync)) {
218  throw new IllegalStateException("thread should synchronize on sync");
219  }
220 
222  if (active) {
223  timer.restart();
224  } else {
225  timer.stop();
226  }
227  }
228 
229  if (this.active == active) {
230  return;
231  }
232 
233  this.active = active;
235  }
236 
237 }
com.realtime.crossfire.jxclient
com.realtime.crossfire.jxclient.stats.PoisonWatcher.stats
final Stats stats
The stats instance to notify.
Definition: PoisonWatcher.java:72
com.realtime.crossfire.jxclient.server
com.realtime.crossfire.jxclient.stats.PoisonWatcher.drawextinfoListener
final CrossfireDrawextinfoListener drawextinfoListener
The drawextinfo listener to receive drawextinfo messages.
Definition: PoisonWatcher.java:89
com.realtime.crossfire.jxclient.server.crossfire.CrossfireServerConnection
Adds encoding/decoding of crossfire protocol packets to a ServerConnection.
Definition: CrossfireServerConnection.java:37
com.realtime.crossfire.jxclient.stats.Stats.CF_POISONED
static final int CF_POISONED
The CS_STAT_CHARACTER_FLAGS bit for a poisoned character.
Definition: Stats.java:549
com.realtime.crossfire.jxclient.stats.PoisonWatcher.active
boolean active
Whether poisoning is active.
Definition: PoisonWatcher.java:77
com.realtime.crossfire.jxclient.stats.PoisonWatcher.PoisonWatcher
PoisonWatcher(@NotNull final Stats stats, @NotNull final CrossfireServerConnection crossfireServerConnection)
Creates a new instance.
Definition: PoisonWatcher.java:185
com.realtime.crossfire.jxclient.stats.PoisonWatcher.statsListener
final StatsListener statsListener
The StatsListener registered to be notified about stat changes.
Definition: PoisonWatcher.java:108
com.realtime.crossfire.jxclient.stats.Stats.addCrossfireStatsListener
void addCrossfireStatsListener(@NotNull final StatsListener statsListener)
Adds a StatsListener to be notified about stat changes.
Definition: Stats.java:963
com.realtime.crossfire.jxclient.stats.PoisonWatcher.CURE_MESSAGE
static final String CURE_MESSAGE
The text message the server sends when the poison is cured via a spell.
Definition: PoisonWatcher.java:60
com.realtime.crossfire.jxclient.stats.PoisonWatcher.serverSupportsPoisonedFlag
boolean serverSupportsPoisonedFlag
Whether the server supports the Stats#CF_POISONED flag.
Definition: PoisonWatcher.java:82
com.realtime.crossfire.jxclient.stats.PoisonWatcher.TIMEOUT_DE_ASSERT
static final int TIMEOUT_DE_ASSERT
Timeout after that the "poisoned" state is reset.
Definition: PoisonWatcher.java:42
com.realtime.crossfire.jxclient.stats.PoisonWatcher.DE_ASSERT_MESSAGE
static final String DE_ASSERT_MESSAGE
The text message the server sends when the poison wears off.
Definition: PoisonWatcher.java:54
com.realtime.crossfire.jxclient.stats.PoisonWatcher.check
void check(@NotNull final String message)
Examines a text message.
Definition: PoisonWatcher.java:200
com.realtime.crossfire.jxclient.stats.Stats
This is the representation of all the statistics of a player, like its speed or its experience.
Definition: Stats.java:44
com.realtime.crossfire.jxclient.stats.PoisonWatcher.ASSERT_MESSAGE
static final String ASSERT_MESSAGE
The text message the server sends in poisoned state.
Definition: PoisonWatcher.java:48
com.realtime.crossfire.jxclient.server.crossfire
Definition: AbstractCrossfireServerConnection.java:23
com.realtime.crossfire.jxclient.stats.PoisonWatcher.timer
final Timer timer
The Timer for turning off the poison symbol.
Definition: PoisonWatcher.java:178
com.realtime.crossfire.jxclient.server.crossfire.CrossfireDrawextinfoListener
Interface for listeners interested in drawextinfo messages received from the Crossfire server.
Definition: CrossfireDrawextinfoListener.java:33
com.realtime.crossfire.jxclient.stats.Stats.C_STAT_POISONED
static final int C_STAT_POISONED
The "is poisoned" indicator.
Definition: Stats.java:462
com.realtime.crossfire
com.realtime
com
com.realtime.crossfire.jxclient.stats.PoisonWatcher.sync
final Object sync
The object used for synchronization.
Definition: PoisonWatcher.java:66
com.realtime.crossfire.jxclient.stats.PoisonWatcher.timeoutEvent
final ActionListener timeoutEvent
The timeout event used to turn off poisoning if the de-assert message was missed.
Definition: PoisonWatcher.java:166
com.realtime.crossfire.jxclient.stats.Stats.CS_STAT_CHARACTER_FLAGS
static final int CS_STAT_CHARACTER_FLAGS
Flags the character's current state.
Definition: Stats.java:330
com.realtime.crossfire.jxclient.stats.PoisonWatcher.setActive
void setActive(final boolean active)
Sets the current poisoned state.
Definition: PoisonWatcher.java:216
com.realtime.crossfire.jxclient.stats.StatsListener
Interface for listeners interested in changes of Stats instances.
Definition: StatsListener.java:32
com.realtime.crossfire.jxclient.stats.PoisonWatcher
Helper class to listen on Stats#CF_POISONED.
Definition: PoisonWatcher.java:36
com.realtime.crossfire.jxclient.stats.Stats.setStat
void setStat(final int statNo, final int value)
Sets the given statistic numerical value.
Definition: Stats.java:789