feat(wired): add upcounter clock controls and checks

This commit is contained in:
Lorenzune
2026-03-19 00:01:59 +01:00
parent d70841d61e
commit 75151accb5
16 changed files with 1356 additions and 28 deletions
@@ -3,6 +3,7 @@ package com.eu.habbo.habbohotel.items;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.interactions.*;
import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTimer;
import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameUpCounter;
import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiPuck;
import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiSphere;
import com.eu.habbo.habbohotel.items.interactions.games.battlebanzai.InteractionBattleBanzaiTeleporter;
@@ -206,6 +207,7 @@ public class ItemManager {
this.interactionsList.add(new ItemInteraction("room_invisible_click_tile", InteractionDefault.class));
this.interactionsList.add(new ItemInteraction("game_timer", InteractionGameTimer.class));
this.interactionsList.add(new ItemInteraction("game_upcounter", InteractionGameUpCounter.class));
this.interactionsList.add(new ItemInteraction("wf_trg_walks_on_furni", WiredTriggerHabboWalkOnFurni.class));
this.interactionsList.add(new ItemInteraction("wf_trg_walks_off_furni", WiredTriggerHabboWalkOffFurni.class));
@@ -216,6 +218,7 @@ public class ItemManager {
this.interactionsList.add(new ItemInteraction("wf_trg_enter_room", WiredTriggerHabboEntersRoom.class));
this.interactionsList.add(new ItemInteraction("wf_trg_leave_room", WiredTriggerHabboLeavesRoom.class));
this.interactionsList.add(new ItemInteraction("wf_trg_says_something", WiredTriggerHabboSaysKeyword.class));
this.interactionsList.add(new ItemInteraction("wf_trg_clock_counter", WiredTriggerClockCounter.class));
this.interactionsList.add(new ItemInteraction("wf_trg_periodically", WiredTriggerRepeater.class));
this.interactionsList.add(new ItemInteraction("wf_trg_period_short", WiredTriggerRepeaterShort.class));
this.interactionsList.add(new ItemInteraction("wf_trg_period_long", WiredTriggerRepeaterLong.class));
@@ -271,6 +274,8 @@ public class ItemManager {
this.interactionsList.add(new ItemInteraction("wf_act_furni_to_furni", WiredEffectFurniToFurni.class));
this.interactionsList.add(new ItemInteraction("wf_act_set_altitude", WiredEffectSetAltitude.class));
this.interactionsList.add(new ItemInteraction("wf_act_rel_mov", WiredEffectRelativeMove.class));
this.interactionsList.add(new ItemInteraction("wf_act_control_clock", WiredEffectControlClock.class));
this.interactionsList.add(new ItemInteraction("wf_act_adjust_clock", WiredEffectAdjustClock.class));
this.interactionsList.add(new ItemInteraction("wf_slc_furni_area", WiredEffectFurniArea.class));
this.interactionsList.add(new ItemInteraction("wf_slc_furni_neighborhood", WiredEffectFurniNeighborhood.class));
this.interactionsList.add(new ItemInteraction("wf_slc_furni_bytype", WiredEffectFurniByType.class));
@@ -303,6 +308,7 @@ public class ItemManager {
this.interactionsList.add(new ItemInteraction("wf_cnd_has_handitem", WiredConditionHabboHasHandItem.class));
this.interactionsList.add(new ItemInteraction("wf_cnd_date_rng_active", WiredConditionDateRangeActive.class));
this.interactionsList.add(new ItemInteraction("wf_cnd_valid_moves", WiredConditionMovementValidation.class));
this.interactionsList.add(new ItemInteraction("wf_cnd_counter_time_matches", WiredConditionCounterTimeMatches.class));
this.interactionsList.add(new ItemInteraction("wf_xtra_random", WiredExtraRandom.class));
@@ -24,13 +24,13 @@ import java.util.Arrays;
public class InteractionGameTimer extends HabboItem {
private static final Logger LOGGER = LoggerFactory.getLogger(InteractionGameTimer.class);
private int[] TIMER_INTERVAL_STEPS = new int[] { 30, 60, 120, 180, 300, 600 };
protected int[] TIMER_INTERVAL_STEPS = new int[] { 30, 60, 120, 180, 300, 600 };
private int baseTime = 0;
private int timeNow = 0;
private boolean isRunning = false;
private boolean isPaused = false;
private boolean threadActive = false;
protected int baseTime = 0;
protected int timeNow = 0;
protected boolean isRunning = false;
protected boolean isPaused = false;
protected boolean threadActive = false;
public enum InteractionGameTimerAction {
START_STOP(1),
@@ -83,7 +83,7 @@ public class InteractionGameTimer extends HabboItem {
parseCustomParams(item);
}
private void parseCustomParams(Item baseItem) {
protected void parseCustomParams(Item baseItem) {
try {
TIMER_INTERVAL_STEPS = Arrays.stream(baseItem.getCustomParams().split(","))
.mapToInt(s -> {
@@ -114,7 +114,7 @@ public class InteractionGameTimer extends HabboItem {
}
}
private void createNewGame(Room room) {
protected void createNewGame(Room room) {
for(Class<? extends Game> gameClass : Emulator.getGameEnvironment().getRoomManager().getGameTypes()) {
Game existingGame = room.getGame(gameClass);
@@ -132,13 +132,13 @@ public class InteractionGameTimer extends HabboItem {
}
}
private void pause(Room room) {
protected void pause(Room room) {
for (Game game : room.getGames()) {
game.pause();
}
}
private void unpause(Room room) {
protected void unpause(Room room) {
for (Game game : room.getGames()) {
game.unpause();
}
@@ -155,7 +155,8 @@ public class InteractionGameTimer extends HabboItem {
public void onPickUp(Room room) {
this.endGame(room);
this.setExtradata(this.baseTime + "\t" + this.baseTime);
this.timeNow = this.getInitialTimeValue();
this.setExtradata(this.timeNow + "\t" + this.baseTime);
this.needsUpdate(true);
}
@@ -165,7 +166,7 @@ public class InteractionGameTimer extends HabboItem {
this.baseTime = this.TIMER_INTERVAL_STEPS[0];
}
this.timeNow = this.baseTime;
this.timeNow = this.getInitialTimeValue();
this.setExtradata(this.timeNow + "\t" + this.baseTime);
room.updateItem(this);
@@ -212,7 +213,7 @@ public class InteractionGameTimer extends HabboItem {
this.createNewGame(room);
this.timeNow = this.baseTime;
this.resetTimeForStart();
this.isRunning = true;
this.isPaused = false;
@@ -221,7 +222,7 @@ public class InteractionGameTimer extends HabboItem {
if (!this.threadActive) {
this.threadActive = true;
Emulator.getThreading().run(new GameTimer(this), 1000);
this.scheduleTimerRunnable(this.getTimerStartDelayMs());
}
} else if (client != null) {
if (!(room.hasRights(client.getHabbo()) || client.getHabbo().hasPermission(Permission.ACC_ANYROOMOWNER)))
@@ -244,13 +245,13 @@ public class InteractionGameTimer extends HabboItem {
if (!this.threadActive) {
this.threadActive = true;
Emulator.getThreading().run(new GameTimer(this));
this.scheduleTimerRunnable(this.getTimerResumeDelayMs());
}
}
} else {
this.isPaused = false;
this.isRunning = true;
this.timeNow = this.baseTime;
this.resetTimeForStart();
room.updateItem(this);
this.createNewGame(room);
@@ -258,7 +259,7 @@ public class InteractionGameTimer extends HabboItem {
if (!this.threadActive) {
this.threadActive = true;
Emulator.getThreading().run(new GameTimer(this), 1000);
this.scheduleTimerRunnable(this.getTimerStartDelayMs());
}
}
@@ -290,15 +291,15 @@ public class InteractionGameTimer extends HabboItem {
if (!isRunning) {
isRunning = true;
isPaused = false;
if(timeNow <= 0) {
timeNow = baseTime;
if (this.shouldResetTimeOnStart()) {
this.resetTimeForStart();
room.updateItem(this);
}
this.createNewGame(room);
WiredManager.triggerGameStarts(room);
if (!threadActive) {
threadActive = true;
Emulator.getThreading().run(new GameTimer(this), 1000);
this.scheduleTimerRunnable(this.getTimerStartDelayMs());
}
}
}
@@ -322,12 +323,12 @@ public class InteractionGameTimer extends HabboItem {
if (!this.threadActive) {
this.threadActive = true;
Emulator.getThreading().run(new GameTimer(this), 1000);
this.scheduleTimerRunnable(this.getTimerResumeDelayMs());
}
}
}
private void increaseTimer(Room room) {
protected void increaseTimer(Room room) {
if (this.isRunning)
return;
@@ -347,13 +348,45 @@ public class InteractionGameTimer extends HabboItem {
}
this.baseTime = baseTime;
this.timeNow = this.getInitialTimeValue();
this.setExtradata(this.timeNow + "\t" + this.baseTime);
this.timeNow = this.baseTime;
room.updateItem(this);
this.needsUpdate(true);
}
protected int getInitialTimeValue() {
return this.baseTime;
}
protected boolean shouldResetTimeOnStart() {
return this.timeNow <= 0;
}
protected void resetTimeForStart() {
this.timeNow = this.baseTime;
}
protected Runnable createTimerRunnable() {
return new GameTimer(this);
}
protected long getTimerStartDelayMs() {
return 1000L;
}
protected long getTimerResumeDelayMs() {
return 0L;
}
protected void scheduleTimerRunnable(long delayMs) {
if (delayMs <= 0) {
Emulator.getThreading().run(this.createTimerRunnable());
return;
}
Emulator.getThreading().run(this.createTimerRunnable(), delayMs);
}
@Override
public String getDatabaseExtraData() {
return this.getExtradata();
@@ -391,4 +424,8 @@ public class InteractionGameTimer extends HabboItem {
public void setTimeNow(int timeNow) {
this.timeNow = timeNow;
}
public int getBaseTime() {
return this.baseTime;
}
}
@@ -0,0 +1,214 @@
package com.eu.habbo.habbohotel.items.interactions.games;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.wired.core.WiredManager;
import com.eu.habbo.threading.runnables.games.GameUpCounter;
import java.sql.ResultSet;
import java.sql.SQLException;
public class InteractionGameUpCounter extends InteractionGameTimer {
private static final int ONE_SECOND_MS = 1000;
private static final int HALF_SECOND_MS = 500;
private static final int MAX_UPCOUNTER_TIME = ((99 * 60) + 59);
private int subSecondOffsetMs = 0;
public InteractionGameUpCounter(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem);
this.normalizeCounterState();
}
public InteractionGameUpCounter(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
super(id, userId, item, extradata, limitedStack, limitedSells);
this.normalizeCounterState();
}
@Override
protected void parseCustomParams(Item baseItem) {
this.TIMER_INTERVAL_STEPS = new int[] { MAX_UPCOUNTER_TIME };
}
private void normalizeCounterState() {
this.baseTime = MAX_UPCOUNTER_TIME;
this.setCurrentTimeInMs(this.parseStoredTime() * ONE_SECOND_MS);
this.setExtradata(this.timeNow + "\t" + this.baseTime);
}
private int parseStoredTime() {
try {
String[] data = this.getExtradata().split("\t");
if (data.length > 0) {
int storedTime = Integer.parseInt(data[0]);
return Math.max(0, Math.min(storedTime, this.baseTime));
}
} catch (Exception ignored) {
}
return Math.max(0, Math.min(this.timeNow, this.baseTime));
}
@Override
protected int getInitialTimeValue() {
return 0;
}
@Override
protected boolean shouldResetTimeOnStart() {
return this.timeNow >= this.baseTime;
}
@Override
protected void resetTimeForStart() {
this.setCurrentTimeInMs(0);
}
@Override
protected void increaseTimer(Room room) {
if (this.isRunning && !this.isPaused) {
return;
}
if (this.isRunning) {
this.endGame(room);
WiredManager.triggerGameEnds(room);
}
this.baseTime = MAX_UPCOUNTER_TIME;
this.setCurrentTimeInMs(0);
this.applyCounterState(room, true);
}
@Override
protected Runnable createTimerRunnable() {
return new GameUpCounter(this);
}
@Override
protected long getTimerStartDelayMs() {
return this.getNextTickDelayMs();
}
@Override
protected long getTimerResumeDelayMs() {
return this.getNextTickDelayMs();
}
public int getCurrentTimeInMs() {
return (this.timeNow * ONE_SECOND_MS) + this.subSecondOffsetMs;
}
public int getMaximumTimeInMs() {
return this.baseTime * ONE_SECOND_MS;
}
public long getNextTickDelayMs() {
return (this.subSecondOffsetMs > 0) ? HALF_SECOND_MS : ONE_SECOND_MS;
}
public void setCurrentTimeInMs(int totalMs) {
int clamped = Math.max(0, Math.min(totalMs, this.getMaximumTimeInMs()));
int remainder = clamped % ONE_SECOND_MS;
this.timeNow = (clamped / ONE_SECOND_MS);
this.subSecondOffsetMs = (remainder >= HALF_SECOND_MS) ? HALF_SECOND_MS : 0;
}
public void advanceCounterInMs(int deltaMs) {
this.setCurrentTimeInMs(this.getCurrentTimeInMs() + deltaMs);
}
private void applyCounterState(Room room, boolean updateRoom) {
this.setExtradata(this.timeNow + "\t" + this.baseTime);
if (updateRoom && room != null) {
room.updateItem(this);
}
this.needsUpdate(true);
}
public void restartFromZero(Room room) {
boolean wasActive = this.isRunning || this.isPaused;
if (wasActive) {
this.endGame(room);
WiredManager.triggerGameEnds(room);
}
this.setCurrentTimeInMs(0);
this.applyCounterState(room, true);
this.startTimer(room);
}
public void stopCounter(Room room) {
boolean wasActive = this.isRunning || this.isPaused;
this.endGame(room);
this.applyCounterState(room, true);
if (wasActive) {
WiredManager.triggerGameEnds(room);
}
}
public void resetCounter(Room room) {
boolean wasActive = this.isRunning || this.isPaused;
this.endGame(room);
this.setCurrentTimeInMs(0);
this.applyCounterState(room, true);
if (wasActive) {
WiredManager.triggerGameEnds(room);
}
}
public void pauseCounter(Room room) {
if (!this.isRunning || this.isPaused) {
return;
}
this.pauseTimer(room);
this.applyCounterState(room, true);
}
public void resumeCounter(Room room) {
if (!this.isPaused) {
return;
}
this.resumeTimer(room);
this.applyCounterState(room, true);
}
public void adjustCounter(Room room, int operator, int minutes, int halfSecondSteps) {
int deltaMs = (Math.max(0, minutes) * 60000) + (Math.max(0, halfSecondSteps) * HALF_SECOND_MS);
int nextTimeMs = this.getCurrentTimeInMs();
switch (operator) {
case 0:
nextTimeMs += deltaMs;
break;
case 1:
nextTimeMs -= deltaMs;
break;
case 2:
default:
nextTimeMs = deltaMs;
break;
}
this.setCurrentTimeInMs(nextTimeMs);
this.applyCounterState(room, true);
}
public void resetOnRoomUnload(Room room) {
this.endGame(room);
this.setThreadActive(false);
this.setCurrentTimeInMs(0);
this.applyCounterState(null, false);
}
}
@@ -0,0 +1,270 @@
package com.eu.habbo.habbohotel.items.interactions.wired.conditions;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredCondition;
import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameUpCounter;
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomUnit;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.habbohotel.wired.WiredConditionType;
import com.eu.habbo.habbohotel.wired.core.WiredContext;
import com.eu.habbo.habbohotel.wired.core.WiredManager;
import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil;
import com.eu.habbo.messages.ServerMessage;
import gnu.trove.set.hash.THashSet;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;
public class WiredConditionCounterTimeMatches extends InteractionWiredCondition {
private static final int COMPARISON_LESS = 0;
private static final int COMPARISON_EQUAL = 1;
private static final int COMPARISON_GREATER = 2;
private static final int MAX_MINUTES = 99;
private static final int MAX_HALF_SECOND_STEPS = 119;
public static final WiredConditionType type = WiredConditionType.COUNTER_TIME_MATCHES;
private final THashSet<HabboItem> items;
private int comparison = COMPARISON_EQUAL;
private int minutes = 0;
private int halfSecondSteps = 0;
private int furniSource = WiredSourceUtil.SOURCE_TRIGGER;
public WiredConditionCounterTimeMatches(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem);
this.items = new THashSet<>();
}
public WiredConditionCounterTimeMatches(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
super(id, userId, item, extradata, limitedStack, limitedSells);
this.items = new THashSet<>();
}
@Override
public boolean evaluate(WiredContext ctx) {
Room room = ctx.room();
if (room == null) {
return false;
}
this.refresh(room);
List<HabboItem> targets = WiredSourceUtil.resolveItems(ctx, this.furniSource, this.items);
if (targets.isEmpty()) {
return false;
}
int targetTimeInMs = this.getTargetTimeInMs();
for (HabboItem item : targets) {
if (!(item instanceof InteractionGameUpCounter)) {
return false;
}
int currentTimeInMs = ((InteractionGameUpCounter) item).getCurrentTimeInMs();
switch (this.comparison) {
case COMPARISON_LESS:
if (currentTimeInMs >= targetTimeInMs) {
return false;
}
break;
case COMPARISON_GREATER:
if (currentTimeInMs <= targetTimeInMs) {
return false;
}
break;
default:
if (currentTimeInMs != targetTimeInMs) {
return false;
}
break;
}
}
return true;
}
@Deprecated
@Override
public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) {
return false;
}
@Override
public String getWiredData() {
return WiredManager.getGson().toJson(new JsonData(
this.comparison,
this.minutes,
this.halfSecondSteps,
this.furniSource,
this.items.stream().map(HabboItem::getId).collect(Collectors.toList())
));
}
@Override
public void loadWiredData(ResultSet set, Room room) throws SQLException {
this.items.clear();
this.comparison = COMPARISON_EQUAL;
this.minutes = 0;
this.halfSecondSteps = 0;
this.furniSource = WiredSourceUtil.SOURCE_TRIGGER;
String wiredData = set.getString("wired_data");
if (wiredData == null || wiredData.isEmpty() || !wiredData.startsWith("{")) {
return;
}
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
if (data == null) {
return;
}
this.comparison = this.normalizeComparison(data.comparison);
this.minutes = this.normalizeMinutes(data.minutes);
this.halfSecondSteps = this.normalizeHalfSecondSteps(data.halfSecondSteps);
this.furniSource = data.furniSource;
if (data.itemIds == null) {
return;
}
for (Integer id : data.itemIds) {
HabboItem item = room.getHabboItem(id);
if (item instanceof InteractionGameUpCounter) {
this.items.add(item);
}
}
}
@Override
public void onPickUp() {
this.items.clear();
this.comparison = COMPARISON_EQUAL;
this.minutes = 0;
this.halfSecondSteps = 0;
this.furniSource = WiredSourceUtil.SOURCE_TRIGGER;
}
@Override
public WiredConditionType getType() {
return type;
}
@Override
public void serializeWiredData(ServerMessage message, Room room) {
this.refresh(room);
message.appendBoolean(false);
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
message.appendInt(this.items.size());
for (HabboItem item : this.items) {
message.appendInt(item.getId());
}
message.appendInt(this.getBaseItem().getSpriteId());
message.appendInt(this.getId());
message.appendString("");
message.appendInt(4);
message.appendInt(this.comparison);
message.appendInt(this.minutes);
message.appendInt(this.halfSecondSteps);
message.appendInt(this.furniSource);
message.appendInt(0);
message.appendInt(this.getType().code);
message.appendInt(0);
message.appendInt(0);
}
@Override
public boolean saveData(WiredSettings settings) {
int[] params = settings.getIntParams();
this.comparison = (params.length > 0) ? this.normalizeComparison(params[0]) : COMPARISON_EQUAL;
this.minutes = (params.length > 1) ? this.normalizeMinutes(params[1]) : 0;
this.halfSecondSteps = (params.length > 2) ? this.normalizeHalfSecondSteps(params[2]) : 0;
this.furniSource = (params.length > 3) ? params[3] : WiredSourceUtil.SOURCE_TRIGGER;
this.items.clear();
if (this.furniSource != WiredSourceUtil.SOURCE_SELECTED) {
return true;
}
Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId());
if (room == null) {
return false;
}
int count = settings.getFurniIds().length;
if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) {
return false;
}
for (int itemId : settings.getFurniIds()) {
HabboItem item = room.getHabboItem(itemId);
if (item instanceof InteractionGameUpCounter) {
this.items.add(item);
}
}
return true;
}
private void refresh(Room room) {
THashSet<HabboItem> remove = new THashSet<>();
for (HabboItem item : this.items) {
HabboItem roomItem = room.getHabboItem(item.getId());
if (!(roomItem instanceof InteractionGameUpCounter)) {
remove.add(item);
}
}
for (HabboItem item : remove) {
this.items.remove(item);
}
}
private int getTargetTimeInMs() {
return (this.minutes * 60_000) + (this.halfSecondSteps * 500);
}
private int normalizeComparison(int value) {
if (value < COMPARISON_LESS || value > COMPARISON_GREATER) {
return COMPARISON_EQUAL;
}
return value;
}
private int normalizeMinutes(int value) {
return Math.max(0, Math.min(MAX_MINUTES, value));
}
private int normalizeHalfSecondSteps(int value) {
return Math.max(0, Math.min(MAX_HALF_SECOND_STEPS, value));
}
static class JsonData {
int comparison;
int minutes;
int halfSecondSteps;
int furniSource;
List<Integer> itemIds;
public JsonData(int comparison, int minutes, int halfSecondSteps, int furniSource, List<Integer> itemIds) {
this.comparison = comparison;
this.minutes = minutes;
this.halfSecondSteps = halfSecondSteps;
this.furniSource = furniSource;
this.itemIds = itemIds;
}
}
}
@@ -0,0 +1,252 @@
package com.eu.habbo.habbohotel.items.interactions.wired.effects;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.gameclients.GameClient;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameUpCounter;
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomUnit;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.habbohotel.wired.WiredEffectType;
import com.eu.habbo.habbohotel.wired.core.WiredContext;
import com.eu.habbo.habbohotel.wired.core.WiredManager;
import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil;
import com.eu.habbo.messages.ServerMessage;
import com.eu.habbo.messages.incoming.wired.WiredSaveException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class WiredEffectAdjustClock extends InteractionWiredEffect {
private static final int OPERATOR_INCREASE = 0;
private static final int OPERATOR_DECREASE = 1;
private static final int OPERATOR_SET = 2;
private static final int MAX_MINUTES = 99;
private static final int MAX_HALF_SECOND_STEPS = 119;
public static final WiredEffectType type = WiredEffectType.ADJUST_CLOCK;
private final List<HabboItem> items = new ArrayList<>();
private int operator = OPERATOR_SET;
private int furniSource = WiredSourceUtil.SOURCE_TRIGGER;
private int minutes = 0;
private int halfSecondSteps = 0;
public WiredEffectAdjustClock(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem);
}
public WiredEffectAdjustClock(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
super(id, userId, item, extradata, limitedStack, limitedSells);
}
@Override
public void execute(WiredContext ctx) {
Room room = ctx.room();
if (room == null) {
return;
}
List<HabboItem> effectiveItems = WiredSourceUtil.resolveItems(ctx, this.furniSource, this.items);
if (this.furniSource == WiredSourceUtil.SOURCE_SELECTED) {
this.items.removeIf(item -> item == null
|| item.getRoomId() != this.getRoomId()
|| room.getHabboItem(item.getId()) == null);
}
for (HabboItem item : effectiveItems) {
if (!(item instanceof InteractionGameUpCounter)) {
continue;
}
((InteractionGameUpCounter) item).adjustCounter(room, this.operator, this.minutes, this.halfSecondSteps);
}
}
@Deprecated
@Override
public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) {
return false;
}
@Override
public String getWiredData() {
return WiredManager.getGson().toJson(new JsonData(
this.getDelay(),
this.items.stream().map(HabboItem::getId).collect(Collectors.toList()),
this.operator,
this.furniSource,
this.minutes,
this.halfSecondSteps
));
}
@Override
public void loadWiredData(ResultSet set, Room room) throws SQLException {
this.items.clear();
String wiredData = set.getString("wired_data");
if (wiredData != null && wiredData.startsWith("{")) {
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
this.setDelay(data.delay);
this.operator = this.normalizeOperator(data.operator);
this.furniSource = data.furniSource;
this.minutes = this.normalizeMinutes(data.minutes);
this.halfSecondSteps = this.normalizeHalfSecondSteps(data.halfSecondSteps);
if (data.itemIds != null) {
for (Integer id : data.itemIds) {
HabboItem item = room.getHabboItem(id);
if (item != null) {
this.items.add(item);
}
}
}
return;
}
this.operator = OPERATOR_SET;
this.furniSource = WiredSourceUtil.SOURCE_TRIGGER;
this.minutes = 0;
this.halfSecondSteps = 0;
this.setDelay(0);
}
@Override
public void onPickUp() {
this.items.clear();
this.operator = OPERATOR_SET;
this.furniSource = WiredSourceUtil.SOURCE_TRIGGER;
this.minutes = 0;
this.halfSecondSteps = 0;
this.setDelay(0);
}
@Override
public WiredEffectType getType() {
return type;
}
@Override
public void serializeWiredData(ServerMessage message, Room room) {
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
itemsSnapshot.removeIf(item -> item == null
|| item.getRoomId() != this.getRoomId()
|| room.getHabboItem(item.getId()) == null);
this.items.clear();
this.items.addAll(itemsSnapshot);
message.appendBoolean(false);
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
message.appendInt(itemsSnapshot.size());
for (HabboItem item : itemsSnapshot) {
message.appendInt(item.getId());
}
message.appendInt(this.getBaseItem().getSpriteId());
message.appendInt(this.getId());
message.appendString("");
message.appendInt(4);
message.appendInt(this.operator);
message.appendInt(this.furniSource);
message.appendInt(this.minutes);
message.appendInt(this.halfSecondSteps);
message.appendInt(0);
message.appendInt(this.getType().code);
message.appendInt(this.getDelay());
message.appendInt(0);
}
@Override
public boolean saveData(WiredSettings settings, GameClient gameClient) throws WiredSaveException {
int[] params = settings.getIntParams();
if (params.length < 4) {
throw new WiredSaveException("Invalid data");
}
this.operator = this.normalizeOperator(params[0]);
this.furniSource = params[1];
this.minutes = this.normalizeMinutes(params[2]);
this.halfSecondSteps = this.normalizeHalfSecondSteps(params[3]);
int delay = settings.getDelay();
if (delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) {
throw new WiredSaveException("Delay too long");
}
Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId());
if (room == null) {
throw new WiredSaveException("Room not found");
}
if (settings.getFurniIds().length > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) {
throw new WiredSaveException("Too many furni selected");
}
List<HabboItem> newItems = new ArrayList<>();
for (int itemId : settings.getFurniIds()) {
HabboItem item = room.getHabboItem(itemId);
if (item == null) {
throw new WiredSaveException(String.format("Item %s not found", itemId));
}
if (!(item instanceof InteractionGameUpCounter)) {
throw new WiredSaveException("wiredfurni.error.require_counter_furni");
}
newItems.add(item);
}
this.items.clear();
this.items.addAll(newItems);
this.setDelay(delay);
return true;
}
private int normalizeOperator(int value) {
if (value < OPERATOR_INCREASE || value > OPERATOR_SET) {
return OPERATOR_SET;
}
return value;
}
private int normalizeMinutes(int value) {
return Math.max(0, Math.min(MAX_MINUTES, value));
}
private int normalizeHalfSecondSteps(int value) {
return Math.max(0, Math.min(MAX_HALF_SECOND_STEPS, value));
}
static class JsonData {
int delay;
List<Integer> itemIds;
int operator;
int furniSource;
int minutes;
int halfSecondSteps;
public JsonData(int delay, List<Integer> itemIds, int operator, int furniSource, int minutes, int halfSecondSteps) {
this.delay = delay;
this.itemIds = itemIds;
this.operator = operator;
this.furniSource = furniSource;
this.minutes = minutes;
this.halfSecondSteps = halfSecondSteps;
}
}
}
@@ -0,0 +1,244 @@
package com.eu.habbo.habbohotel.items.interactions.wired.effects;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.gameclients.GameClient;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredEffect;
import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameUpCounter;
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomUnit;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.habbohotel.wired.WiredEffectType;
import com.eu.habbo.habbohotel.wired.core.WiredContext;
import com.eu.habbo.habbohotel.wired.core.WiredManager;
import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil;
import com.eu.habbo.messages.ServerMessage;
import com.eu.habbo.messages.incoming.wired.WiredSaveException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class WiredEffectControlClock extends InteractionWiredEffect {
private static final int ACTION_START = 0;
private static final int ACTION_STOP = 1;
private static final int ACTION_RESET = 2;
private static final int ACTION_PAUSE = 3;
private static final int ACTION_RESUME = 4;
public static final WiredEffectType type = WiredEffectType.CONTROL_CLOCK;
private final List<HabboItem> items = new ArrayList<>();
private int action = ACTION_START;
private int furniSource = WiredSourceUtil.SOURCE_TRIGGER;
public WiredEffectControlClock(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem);
}
public WiredEffectControlClock(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
super(id, userId, item, extradata, limitedStack, limitedSells);
}
@Override
public void execute(WiredContext ctx) {
Room room = ctx.room();
if (room == null) {
return;
}
List<HabboItem> effectiveItems = WiredSourceUtil.resolveItems(ctx, this.furniSource, this.items);
if (this.furniSource == WiredSourceUtil.SOURCE_SELECTED) {
this.items.removeIf(item -> item == null
|| item.getRoomId() != this.getRoomId()
|| room.getHabboItem(item.getId()) == null);
}
for (HabboItem item : effectiveItems) {
if (!(item instanceof InteractionGameUpCounter)) {
continue;
}
InteractionGameUpCounter counter = (InteractionGameUpCounter) item;
switch (this.action) {
case ACTION_START:
counter.restartFromZero(room);
break;
case ACTION_STOP:
counter.stopCounter(room);
break;
case ACTION_RESET:
counter.resetCounter(room);
break;
case ACTION_PAUSE:
counter.pauseCounter(room);
break;
case ACTION_RESUME:
counter.resumeCounter(room);
break;
}
}
}
@Deprecated
@Override
public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) {
return false;
}
@Override
public String getWiredData() {
return WiredManager.getGson().toJson(new JsonData(
this.getDelay(),
this.items.stream().map(HabboItem::getId).collect(Collectors.toList()),
this.action,
this.furniSource
));
}
@Override
public void loadWiredData(ResultSet set, Room room) throws SQLException {
this.items.clear();
String wiredData = set.getString("wired_data");
if (wiredData != null && wiredData.startsWith("{")) {
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
this.setDelay(data.delay);
this.action = this.normalizeAction(data.action);
this.furniSource = data.furniSource;
if (data.itemIds != null) {
for (Integer id : data.itemIds) {
HabboItem item = room.getHabboItem(id);
if (item != null) {
this.items.add(item);
}
}
}
return;
}
this.action = ACTION_START;
this.furniSource = WiredSourceUtil.SOURCE_TRIGGER;
this.setDelay(0);
}
@Override
public void onPickUp() {
this.items.clear();
this.action = ACTION_START;
this.furniSource = WiredSourceUtil.SOURCE_TRIGGER;
this.setDelay(0);
}
@Override
public WiredEffectType getType() {
return type;
}
@Override
public void serializeWiredData(ServerMessage message, Room room) {
List<HabboItem> itemsSnapshot = new ArrayList<>(this.items);
itemsSnapshot.removeIf(item -> item == null
|| item.getRoomId() != this.getRoomId()
|| room.getHabboItem(item.getId()) == null);
this.items.clear();
this.items.addAll(itemsSnapshot);
message.appendBoolean(false);
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
message.appendInt(itemsSnapshot.size());
for (HabboItem item : itemsSnapshot) {
message.appendInt(item.getId());
}
message.appendInt(this.getBaseItem().getSpriteId());
message.appendInt(this.getId());
message.appendString("");
message.appendInt(2);
message.appendInt(this.action);
message.appendInt(this.furniSource);
message.appendInt(0);
message.appendInt(this.getType().code);
message.appendInt(this.getDelay());
message.appendInt(0);
}
@Override
public boolean saveData(WiredSettings settings, GameClient gameClient) throws WiredSaveException {
int[] params = settings.getIntParams();
if (params.length < 2) {
throw new WiredSaveException("Invalid data");
}
this.action = this.normalizeAction(params[0]);
this.furniSource = params[1];
int delay = settings.getDelay();
if (delay > Emulator.getConfig().getInt("hotel.wired.max_delay", 20)) {
throw new WiredSaveException("Delay too long");
}
Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId());
if (room == null) {
throw new WiredSaveException("Room not found");
}
if (settings.getFurniIds().length > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) {
throw new WiredSaveException("Too many furni selected");
}
List<HabboItem> newItems = new ArrayList<>();
for (int itemId : settings.getFurniIds()) {
HabboItem item = room.getHabboItem(itemId);
if (item == null) {
throw new WiredSaveException(String.format("Item %s not found", itemId));
}
if (!(item instanceof InteractionGameUpCounter)) {
throw new WiredSaveException("wiredfurni.error.require_counter_furni");
}
newItems.add(item);
}
this.items.clear();
this.items.addAll(newItems);
this.setDelay(delay);
return true;
}
private int normalizeAction(int value) {
if (value < ACTION_START || value > ACTION_RESUME) {
return ACTION_START;
}
return value;
}
static class JsonData {
int delay;
List<Integer> itemIds;
int action;
int furniSource;
public JsonData(int delay, List<Integer> itemIds, int action, int furniSource) {
this.delay = delay;
this.itemIds = itemIds;
this.action = action;
this.furniSource = furniSource;
}
}
}
@@ -0,0 +1,229 @@
package com.eu.habbo.habbohotel.items.interactions.wired.triggers;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.items.interactions.InteractionWiredTrigger;
import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameUpCounter;
import com.eu.habbo.habbohotel.items.interactions.wired.WiredSettings;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.rooms.RoomUnit;
import com.eu.habbo.habbohotel.users.HabboItem;
import com.eu.habbo.habbohotel.wired.WiredTriggerType;
import com.eu.habbo.habbohotel.wired.core.WiredEvent;
import com.eu.habbo.habbohotel.wired.core.WiredManager;
import com.eu.habbo.habbohotel.wired.core.WiredSourceUtil;
import com.eu.habbo.messages.ServerMessage;
import gnu.trove.set.hash.THashSet;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;
public class WiredTriggerClockCounter extends InteractionWiredTrigger {
private static final int MAX_MINUTES = 99;
private static final int MAX_HALF_SECOND_STEPS = 119;
public static final WiredTriggerType type = WiredTriggerType.CLOCK_COUNTER;
private final THashSet<HabboItem> items;
private int minutes = 0;
private int halfSecondSteps = 0;
private int furniSource = WiredSourceUtil.SOURCE_TRIGGER;
public WiredTriggerClockCounter(ResultSet set, Item baseItem) throws SQLException {
super(set, baseItem);
this.items = new THashSet<>();
}
public WiredTriggerClockCounter(int id, int userId, Item item, String extradata, int limitedStack, int limitedSells) {
super(id, userId, item, extradata, limitedStack, limitedSells);
this.items = new THashSet<>();
}
@Override
public boolean matches(HabboItem triggerItem, WiredEvent event) {
HabboItem sourceItem = event.getSourceItem().orElse(null);
if (!(sourceItem instanceof InteractionGameUpCounter)) {
return false;
}
if (((InteractionGameUpCounter) sourceItem).getCurrentTimeInMs() != this.getTargetTimeInMs()) {
return false;
}
return (this.furniSource != WiredSourceUtil.SOURCE_SELECTED) || this.items.contains(sourceItem);
}
@Deprecated
@Override
public boolean execute(RoomUnit roomUnit, Room room, Object[] stuff) {
return false;
}
@Override
public WiredTriggerType getType() {
return type;
}
@Override
public void serializeWiredData(ServerMessage message, Room room) {
this.refresh(room);
message.appendBoolean(false);
message.appendInt(WiredManager.MAXIMUM_FURNI_SELECTION);
message.appendInt(this.items.size());
for (HabboItem item : this.items) {
message.appendInt(item.getId());
}
message.appendInt(this.getBaseItem().getSpriteId());
message.appendInt(this.getId());
message.appendString("");
message.appendInt(3);
message.appendInt(this.minutes);
message.appendInt(this.halfSecondSteps);
message.appendInt(this.furniSource);
message.appendInt(0);
message.appendInt(this.getType().code);
message.appendInt(0);
message.appendInt(0);
}
@Override
public boolean saveData(WiredSettings settings) {
int[] params = settings.getIntParams();
this.minutes = (params.length > 0) ? this.normalizeMinutes(params[0]) : 0;
this.halfSecondSteps = (params.length > 1) ? this.normalizeHalfSecondSteps(params[1]) : 0;
this.furniSource = (params.length > 2) ? this.normalizeFurniSource(params[2]) : WiredSourceUtil.SOURCE_TRIGGER;
this.items.clear();
if (this.furniSource != WiredSourceUtil.SOURCE_SELECTED) {
return true;
}
Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(this.getRoomId());
if (room == null) {
return false;
}
int count = settings.getFurniIds().length;
if (count > Emulator.getConfig().getInt("hotel.wired.furni.selection.count")) {
return false;
}
for (int itemId : settings.getFurniIds()) {
HabboItem item = room.getHabboItem(itemId);
if (item instanceof InteractionGameUpCounter) {
this.items.add(item);
}
}
return true;
}
@Override
public String getWiredData() {
return WiredManager.getGson().toJson(new JsonData(
this.minutes,
this.halfSecondSteps,
this.furniSource,
this.items.stream().map(HabboItem::getId).collect(Collectors.toList())
));
}
@Override
public void loadWiredData(ResultSet set, Room room) throws SQLException {
this.items.clear();
this.minutes = 0;
this.halfSecondSteps = 0;
this.furniSource = WiredSourceUtil.SOURCE_TRIGGER;
String wiredData = set.getString("wired_data");
if (wiredData == null || wiredData.isEmpty()) {
return;
}
if (!wiredData.startsWith("{")) {
return;
}
JsonData data = WiredManager.getGson().fromJson(wiredData, JsonData.class);
if (data == null) {
return;
}
this.minutes = this.normalizeMinutes(data.minutes);
this.halfSecondSteps = this.normalizeHalfSecondSteps(data.halfSecondSteps);
this.furniSource = this.normalizeFurniSource(data.furniSource);
if (data.itemIds == null) {
return;
}
for (Integer id : data.itemIds) {
HabboItem item = room.getHabboItem(id);
if (item instanceof InteractionGameUpCounter) {
this.items.add(item);
}
}
}
@Override
public void onPickUp() {
this.items.clear();
this.minutes = 0;
this.halfSecondSteps = 0;
this.furniSource = WiredSourceUtil.SOURCE_TRIGGER;
}
private void refresh(Room room) {
THashSet<HabboItem> remove = new THashSet<>();
for (HabboItem item : this.items) {
HabboItem roomItem = room.getHabboItem(item.getId());
if (!(roomItem instanceof InteractionGameUpCounter)) {
remove.add(item);
}
}
for (HabboItem item : remove) {
this.items.remove(item);
}
}
private int getTargetTimeInMs() {
return (this.minutes * 60_000) + (this.halfSecondSteps * 500);
}
private int normalizeMinutes(int value) {
return Math.max(0, Math.min(MAX_MINUTES, value));
}
private int normalizeHalfSecondSteps(int value) {
return Math.max(0, Math.min(MAX_HALF_SECOND_STEPS, value));
}
private int normalizeFurniSource(int value) {
return (value == WiredSourceUtil.SOURCE_SELECTED) ? WiredSourceUtil.SOURCE_SELECTED : WiredSourceUtil.SOURCE_TRIGGER;
}
static class JsonData {
int minutes;
int halfSecondSteps;
int furniSource;
List<Integer> itemIds;
public JsonData(int minutes, int halfSecondSteps, int furniSource, List<Integer> itemIds) {
this.minutes = minutes;
this.halfSecondSteps = halfSecondSteps;
this.furniSource = furniSource;
this.itemIds = itemIds;
}
}
}
@@ -9,6 +9,7 @@ import com.eu.habbo.habbohotel.items.FurnitureType;
import com.eu.habbo.habbohotel.items.Item;
import com.eu.habbo.habbohotel.items.interactions.*;
import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameTimer;
import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameUpCounter;
import com.eu.habbo.habbohotel.permissions.Permission;
import com.eu.habbo.habbohotel.pets.Pet;
import com.eu.habbo.habbohotel.pets.PetManager;
@@ -898,7 +899,11 @@ public class Room implements Comparable<Room>, ISerialize, Runnable {
}
for (InteractionGameTimer timer : this.getRoomSpecialTypes().getGameTimers().values()) {
timer.setRunning(false);
if (timer instanceof InteractionGameUpCounter) {
((InteractionGameUpCounter) timer).resetOnRoomUnload(this);
} else {
timer.setRunning(false);
}
}
for (Game game : this.games) {
@@ -294,7 +294,10 @@ public abstract class HabboItem implements Runnable, IEventTriggers {
}
}
if ((this.getBaseItem().getStateCount() > 1 && !(this instanceof InteractionDice)) || Arrays.asList(HabboItem.TOGGLING_INTERACTIONS).contains(this.getClass()) || (objects != null && objects.length == 1 && objects[0].equals("TOGGLE_OVERRIDE"))) {
boolean isTogglingInteraction = Arrays.stream(HabboItem.TOGGLING_INTERACTIONS)
.anyMatch(type -> type.isAssignableFrom(this.getClass()));
if ((this.getBaseItem().getStateCount() > 1 && !(this instanceof InteractionDice)) || isTogglingInteraction || (objects != null && objects.length == 1 && objects[0].equals("TOGGLE_OVERRIDE"))) {
WiredManager.triggerFurniStateChanged(room, client.getHabbo().getRoomUnit(), this);
}
}
@@ -25,7 +25,8 @@ public enum WiredConditionType {
NOT_ACTOR_WEARS_EFFECT(23),
DATE_RANGE(24),
ACTOR_HAS_HANDITEM(25),
MOVEMENT_VALIDATION(26); // i dont know what type it is but its needed
MOVEMENT_VALIDATION(26), // i dont know what type it is but its needed
COUNTER_TIME_MATCHES(27);
public final int code;
@@ -39,7 +39,9 @@ public enum WiredEffectType {
USER_TO_FURNI(37),
FURNI_TO_FURNI(38),
SET_ALTITUDE(39),
RELATIVE_MOVE(40);
RELATIVE_MOVE(40),
CONTROL_CLOCK(41),
ADJUST_CLOCK(42);
public final int code;
@@ -21,6 +21,7 @@ public enum WiredTriggerType {
CLICKS_TILE(19),
CLICKS_USER(20),
USER_PERFORMS_ACTION(21),
CLOCK_COUNTER(22),
SAY_COMMAND(0),
IDLES(11),
UNIDLES(11),
@@ -63,6 +63,9 @@ public final class WiredEvent {
/** Timer fires periodically/repeatedly */
TIMER_REPEAT(WiredTriggerType.PERIODICALLY),
/** Up-counter reaches a configured elapsed time */
CLOCK_COUNTER_REACHED(WiredTriggerType.CLOCK_COUNTER),
/** Long timer repeat */
TIMER_REPEAT_LONG(WiredTriggerType.PERIODICALLY_LONG),
@@ -355,6 +355,15 @@ public final class WiredManager {
return handleEvent(event);
}
public static boolean triggerClockCounter(Room room, HabboItem counterItem) {
if (!isEnabled() || room == null || counterItem == null) {
return false;
}
WiredEvent event = WiredEvents.clockCounter(room, counterItem);
return handleEvent(event);
}
/**
* Trigger a long periodic timer.
*/
@@ -218,6 +218,12 @@ public final class WiredEvents {
.build();
}
public static WiredEvent clockCounter(Room room, HabboItem counterItem) {
return WiredEvent.builder(WiredEvent.Type.CLOCK_COUNTER_REACHED, room)
.sourceItem(counterItem)
.build();
}
/**
* Create an event for a long periodic timer.
* @param room the room
@@ -0,0 +1,46 @@
package com.eu.habbo.threading.runnables.games;
import com.eu.habbo.Emulator;
import com.eu.habbo.habbohotel.items.interactions.games.InteractionGameUpCounter;
import com.eu.habbo.habbohotel.rooms.Room;
import com.eu.habbo.habbohotel.wired.core.WiredManager;
public class GameUpCounter implements Runnable {
private final InteractionGameUpCounter timer;
public GameUpCounter(InteractionGameUpCounter timer) {
this.timer = timer;
}
@Override
public void run() {
if (timer.getRoomId() == 0) {
timer.setRunning(false);
timer.setThreadActive(false);
return;
}
Room room = Emulator.getGameEnvironment().getRoomManager().getRoom(timer.getRoomId());
if (room == null || !timer.isRunning() || timer.isPaused()) {
timer.setThreadActive(false);
return;
}
int tickDelayMs = (int) timer.getNextTickDelayMs();
timer.advanceCounterInMs(tickDelayMs);
WiredManager.triggerClockCounter(room, timer);
if (timer.getCurrentTimeInMs() < timer.getMaximumTimeInMs()) {
timer.setThreadActive(true);
Emulator.getThreading().run(this, timer.getNextTickDelayMs());
} else {
timer.setThreadActive(false);
timer.setCurrentTimeInMs(timer.getMaximumTimeInMs());
timer.endGame(room);
WiredManager.triggerGameEnds(room);
}
room.updateItem(timer);
}
}