RuneHive-Game
Loading...
Searching...
No Matches
World.java
Go to the documentation of this file.
1package com.runehive.game.world;
2
3import com.runehive.Config;
4import com.runehive.content.activity.impl.pestcontrol.PestControlLobby;
5import com.runehive.content.bot.PlayerBot;
6import com.runehive.content.clanchannel.ClanRepository;
7import com.runehive.content.tradingpost.TradingPost;
8import com.runehive.game.Graphic;
9import com.runehive.game.Projectile;
10import com.runehive.game.ProjectileTest;
11import com.runehive.game.event.bus.DataBus;
12import com.runehive.game.event.listener.WorldEventListener;
13import com.runehive.game.task.Task;
14import com.runehive.game.task.TaskDeadlockWatcher;
15import com.runehive.game.task.TaskManager;
16import com.runehive.game.task.impl.PlayerRemovalTask;
17import com.runehive.game.task.impl.SystemUpdateEvent;
18import com.runehive.game.world.entity.MobList;
19import com.runehive.game.world.entity.mob.Mob;
20import com.runehive.game.world.entity.mob.npc.Npc;
21import com.runehive.game.world.entity.mob.player.Player;
22import com.runehive.game.world.entity.mob.player.PlayerRight;
23import com.runehive.game.world.entity.mob.player.persist.PlayerSerializer;
24import com.runehive.game.world.object.GameObject;
25import com.runehive.game.world.position.Area;
26import com.runehive.game.world.position.Position;
27import com.runehive.game.world.region.Region;
28import com.runehive.game.world.region.RegionManager;
29import com.runehive.net.packet.out.*;
30import com.runehive.util.GameSaver;
31import com.runehive.util.Utility;
32import org.apache.logging.log4j.LogManager;
33import org.apache.logging.log4j.Logger;
34
35import java.util.*;
36import java.util.concurrent.ConcurrentLinkedQueue;
37import java.util.concurrent.atomic.AtomicBoolean;
38import java.util.function.Predicate;
39
40/**
41 * Represents the game world.
42 *
43 * @author Daniel
44 * @author Michael
45 */
46public final class World {
47
48 private static final Logger logger = LogManager.getLogger(World.class);
49
50 /** The players registered in this world. */
52
53 /** The npcs registered in this world. */
55
56 /** The {@link Player}s waiting to login. */
57 private final Queue<Player> logins = new ConcurrentLinkedQueue<>();
58
59 /** The {@link Player}s waiting to onLogout. */
60 private final Queue<Player> logouts = new ConcurrentLinkedQueue<>();
61
62 /** The task manager. */
63 private final TaskManager taskManager;
64 /** The task deadlock watcher relies on the TaskManager **/
66
67 /** The thread to watch task deadlocks on **/
68 private final Thread taskDeadlockWatcherThread;
69 /** The region manager. */
71
72 public static final AtomicBoolean update = new AtomicBoolean(false);
73
74 public static int addition = 0;
75
76
77 private static final DataBus dataBus = DataBus.getInstance();
78
79 /** The world instance. */
80 private static final World WORLD = new World();
81
82 private World() {
83 dataBus.subscribe(new WorldEventListener());
87 taskDeadlockWatcherThread.setName("TaskDeadlockWatcher");
89 }
90
91 /** Handles the world sequencing. */
92 public void sequence() {
93
94 }
95
96 /** Saves all the game data. */
97 public static void save() {
98 System.out.println("Saving osroyale...");
99 get().players.forEach(PlayerSerializer::save);
100 logger.info("All players were successfully saved.");
101 /* GlobalRecords.save();
102 logger.info("All global records were successfully saved.");*/
104 logger.info("All clans were successfully saved.");
107 logger.info("All trading post history was successfully saved");
108 GameSaver.save();
109 logger.info("All game data were successfully saved.");
110 }
111
112 /** Updates the server. */
113 public static void update(int time) {
114 if (!update.get()) {
115 update.set(true);
116 schedule(new SystemUpdateEvent(time));
117 get().players.stream().forEach(it -> it.send(new SendGameMessage(0, time / 100, "System update" + " in:")));
118 }
119 }
120
121 /** Shuts down the server. */
122 public static void shutdown() {
123 System.out.println("shutting down...");
124 get().taskDeadlockWatcher.requestExit();
125 System.exit(0);
126 }
127
128 /** Handles queueing the player logins. */
129 public static void queueLogin(Player player) {
130 if (player.isBot) {
131 get().logins.add(player);
132 } else {
133 player.getSession().ifPresent(it -> World.get().logins.add(player));
134 }
135 }
136
137 /** Handles queueing the player logouts. */
138 public static void queueLogout(Player player) {
139 if (player == null || get().logouts.contains(player)) {
140 return;
141 }
142
143 get().logouts.add(player);
144 }
145
146 /** Gets a player by name. */
147 public static Optional<Player> search(String name) {
148 for (Player player : get().players) {
149 if (player == null) {
150 continue;
151 }
152
153 if (player.getUsername().equalsIgnoreCase(name)) {
154 return Optional.of(player);
155 }
156 }
157 return Optional.empty();
158 }
159
160 public static Optional<Player> searchAll(String name) {
161 for (Player player : get().players) {
162 if (player == null) {
163 continue;
164 }
165
166 if (player.getUsername().equalsIgnoreCase(name)) {
167 return Optional.of(player);
168 }
169 }
170
171 for (Player player : World.get().getLogins()) {
172 if (player == null) {
173 continue;
174 }
175
176 if (player.getUsername().equalsIgnoreCase(name)) {
177 return Optional.of(player);
178 }
179 }
180 return Optional.empty();
181 }
182
183 public static Optional<Player> getPlayerByHash(long usernameHash) {
184 for (Player player : World.getPlayers()) {
185 if (Objects.equals(player.usernameLong, usernameHash))
186 return Optional.of(player);
187 }
188 return Optional.empty();
189 }
190
191 public static Optional<Player> getPlayerByName(String username) {
192 for (Player player : World.getPlayers()) {
193 if (Objects.equals(player.getUsername(), username))
194 return Optional.of(player);
195 }
196 return Optional.empty();
197 }
198
199 /** Gets a player by index. */
200 public static Optional<Player> getPlayerBySlot(int index) {
201 for (Player player : World.getPlayers()) {
202 if (player.getIndex() == index)
203 return Optional.of(player);
204 }
205 return Optional.empty();
206 }
207
208 /** Gets an npc by index. */
209 public static Optional<Npc> getNpcBySlot(int index) {
210 for (Npc npc : World.getNpcs()) {
211 if (npc.getIndex() == index)
212 return Optional.of(npc);
213 }
214 return Optional.empty();
215 }
216
217 public static void kickPlayer(Player other) {
218 other.send(new SendLogout());
219 queueLogout(other);
220 }
221
222 public static void kickPlayer(Predicate<Player> condition) {
223 for (Player player : get().players) {
224 if (player.isBot)
225 continue;
226 if (!condition.test(player))
227 continue;
228 player.send(new SendLogout());
229 queueLogout(player);
230 }
231 }
232
233 public void process() {
234 try {
235 taskManager.processTasks();
236 } catch (Exception ex) {
237 logger.error("Error sequencing task manager", ex);
238 }
239 try {
241 } catch (Exception ex) {
242 logger.error("Error sequencing pest control.", ex);
243 }
244 }
245
246 /** Submits a new event. */
247 public static void schedule(Task task) {
248 get().taskManager.schedule(task);
249 }
250
251 /** Executes a runnable on a delay. */
252 public static void schedule(int delay, Runnable runnable) {
253 schedule(new Task(delay) {
254 @Override
255 public void execute() {
256 runnable.run();
257 cancel();
258 }
259 });
260 }
261
262 /** Executes a runnable on a 1 tick delay. */
263 public static void schedule(Runnable runnable) {
264 schedule(1, runnable);
265 }
266
267 /** Sends a graphic to the world. */
268 public static void sendGraphic(Graphic graphic, Position position, int instance) {
269 for (Player player : getPlayers()) {
270 if (player.instance != instance)
271 continue;
273 continue;
274 player.send(new SendGraphic(graphic, position));
275 }
276 }
277 public static void sendGraphic(Graphic graphic, Position position) {
278 get().players.stream().filter(player -> Utility.withinDistance(player, position, Region.VIEW_DISTANCE))
279 .forEach(player -> {
280 player.send(new SendGraphic(graphic, position));
281 });
282 }
283 /** Sends a world object animation. */
284 public static void sendObjectAnimation(int animation, GameObject object) {
285 for (Player player : getPlayers()) {
286 if (player.instance != object.getInstancedHeight())
287 continue;
288 if (!Utility.withinDistance(player, object.getPosition(), Region.VIEW_DISTANCE))
289 continue;
290 player.send(new SendObjectAnimation(animation, object));
291 }
292 }
293
294 /** Sends a world projectile. */
295 public static void sendProjectile(Projectile projectile, Position position, int instance, int lock, byte offsetX, byte offsetY) {
296 for (Player player : getPlayers()) {
297 if (player.instance != instance)
298 continue;
300 continue;
301 player.send(new SendProjectile(projectile, position, lock, offsetX, offsetY));
302
303 }
304 }
305
306 /** Sends a world projectile. */
307 public static void sendProjectile(Mob source, Mob target, Projectile projectile) {
308 int lockon = target.isNpc() ? target.getIndex() + 1 : -target.getIndex() - 1;
309 int sourceX = source.getX() + source.width() / 2, sourceY = source.getY() + source.length() / 2;
310 int targetX = target.getX() + target.width() / 2, targetY = target.getY() + target.length() / 2;
311 byte offsetX = (byte) (targetX - sourceX);
312 byte offsetY = (byte) (targetY - sourceY);
313 Position center = new Position(sourceX, sourceY);
314
315 for (Player player : getPlayers()) {
316 if (source.instance != player.instance)
317 continue;
318 if (!Utility.withinDistance(target, player, Region.VIEW_DISTANCE))
319 continue;
320 player.send(new SendProjectile(projectile, center, lockon, offsetX, offsetY));
321 }
322 }
323
324 public static void sendProjectile(Position source, Mob target, Projectile projectile) {
325 int lockon = target.isNpc() ? target.getIndex() + 1 : -target.getIndex() - 1;
326 int sourceX = source.getX(), sourceY = source.getY();
327 int targetX = target.getX() + target.width() / 2, targetY = target.getY() + target.length() / 2;
328 byte offsetX = (byte) (targetX - sourceX);
329 byte offsetY = (byte) (targetY - sourceY);
330 Position center = new Position(sourceX, sourceY);
331
332 for (Player player : getPlayers()) {
333 if (!Utility.withinDistance(target, player, Region.VIEW_DISTANCE))
334 continue;
335 player.send(new SendProjectile(projectile, center, lockon, offsetX, offsetY));
336 }
337 }
338
339 /** Sends a world projectile. */
340 public static void sendProjectile(Mob source, Position target, Projectile projectile) {
341 int sourceX = source.getX() + source.width() / 2, sourceY = source.getY() + source.length() / 2;
342 Position center = new Position(sourceX, sourceY);
343 byte offsetX = (byte) (target.getX() - sourceX);
344 byte offsetY = (byte) (target.getY() - sourceY);
345 for (Player player : getPlayers()) {
346 if (source.instance != player.instance)
347 continue;
348 if (!Utility.withinDistance(player, target, Region.VIEW_DISTANCE))
349 continue;
350 player.send(new SendProjectile(projectile, center, -1, offsetX, offsetY));
351 }
352 }
353
354 public static void sendProjectile(Position source, Position target, Projectile projectile) {
355 int sourceX = source.getX(), sourceY = source.getY();
356 Position center = new Position(sourceX, sourceY);
357 byte offsetX = (byte) (target.getX() - sourceX);
358 byte offsetY = (byte) (target.getY() - sourceY);
359 for (Player player : getPlayers()) {
360 if (!Utility.withinDistance(player, target, Region.VIEW_DISTANCE))
361 continue;
362 player.send(new SendProjectile(projectile, center, -1, offsetX, offsetY));
363 }
364 }
365
366 public static int executeProjectile(Mob entity, ProjectileTest projectile) {
367 if (projectile == null) {
368 return 0;
369 }
370 Position source = projectile.getStart();
371 Position target = projectile.getTarget();
372 if (source == null || target == null) {
373 return 0;
374 }
375 Position delta = projectile.getTarget().getDelta(source, target);
376
377 int distance = entity.getPosition().getChevDistance(target);
378
379 if (distance <= 60) {
380 int creatorSize = projectile.getCreatorSize() == -1 ? 1 : projectile.getCreatorSize(); //TODO size
381
382 for (Player player : getPlayers()) {
383 if (player == null) {
384 continue;
385 }
386
387 if (source.isViewableFrom(player.getPosition())) {
388 player.send(new SendProjectileTestPacket(source, delta, projectile.getSlope(), projectile.getSpeed(), projectile.getProjectileId(), projectile.getStartHeight(), projectile.getEndHeight(), projectile.getLockon(), projectile.getDelay(), creatorSize, projectile.getStartDistanceOffset()));
389 }
390 }
391 }
392 return projectile.getHitDelay(distance);
393 }
394
395 /** Sends a global message. */
396 public static void sendMessage(String... messages) {
397 if (com.runehive.Config.DISABLE_BROADCASTS) return;
398 for (Player player : getPlayers()) {
399 if (player != null)
400 player.message(messages);
401 }
402 }
403
404 /** Sends a global message with an exception. */
405 public static void sendMessage(String message, Predicate<Player> filter) {
406 if (com.runehive.Config.DISABLE_BROADCASTS) return;
407 for (Player player : getPlayers()) {
408 if (player != null && filter.test(player))
409 player.message(message);
410 }
411 }
412
413 public static void sendStaffMessage(String... messages) {
414 for (Player player : getStaff()) {
415 player.message(messages);
416 }
417 }
418
419 /** Sends a game message. */
420 public static void sendBroadcast(int time, String message, boolean countdown) {
421 get().players.stream().forEach($it -> {
422 $it.send(new SendGameMessage(countdown ? 0 : 1, time, Utility.capitalizeSentence(message)));
423 $it.send(new SendMessage("<col=2C7526>Broadcast: </col>" + Utility.capitalizeSentence(message)));
424 });
425 }
426
427 public void dequeLogins() {
428 if (logins.isEmpty()) {
429 return;
430 }
431
432 for (int index = 0; index < Config.LOGIN_THESHOLD; index++) {
433 Player player = logins.poll();
434
435 if (player == null) {
436 break;
437 }
438
439 try {
440 player.register();
441 } catch (Exception ex) {
442 logger.error(String.format("error registering %s", player), ex);
443 }
444
445 }
446 }
447
448 public void dequeLogouts() {
449 if (logouts.isEmpty()) {
450 return;
451 }
452
453 for (int index = 0; index < Config.LOGOUT_THESHOLD; index++) {
454 Player player = logouts.poll();
455
456 if (player == null) {
457 break;
458 }
459
460 World.schedule(new PlayerRemovalTask(player, false));
461 }
462 }
463
465 int count = 0;
466 for (Player player : getPlayers()) {
467 if (player != null && Area.inWildernessResource(player))
468 count++;
469 }
470 return count;
471 }
472
473 /** Sends a kill feed notification. */
474 public static void sendKillFeed(final Mob killer, final Mob victim) {
475 if (victim.isNpc()) {
476 if (Area.inWilderness(victim)) {
477 return;
478 }
479 if (!victim.getNpc().npcAssistant.isBoss()) {
480 return;
481 }
482 }
483
484 for (final Player player : getPlayers()) {
485 player.send(new SendKillFeed(killer, victim));
486 }
487 }
488
489 /** Gets the amount of valid players online. */
490 public static int getPlayerCount() {
491 return Math.toIntExact(getPlayers().size() + addition);
492 }
493
494 public static int getBotCount() {
495 return PlayerBot.BOT_COUNT.get();
496 }
497
498 public static int getStaffCount() {
499 int count = 0;
500
501 for (Player player : getPlayers()) {
502 if (player != null && (PlayerRight.isModerator(player) || player.right == PlayerRight.HELPER))
503 count++;
504 }
505
506 return count;
507 }
508
509 public static int getWildernessCount() {
510 int count = 0;
511
512 for (Player player : getPlayers()) {
513 if (player != null && !player.isBot && Area.inWilderness(player))
514 count++;
515 }
516
517 return count;
518 }
519
520 /** Gets the staff players currently online. */
521 public static List<Player> getStaff() {
522 List<Player> staff = new ArrayList<>();
523
524 for (Player player : getPlayers()) {
525 if (player != null && (PlayerRight.isModerator(player) || player.right == PlayerRight.HELPER))
526 staff.add(player);
527 }
528
529 return staff;
530 }
531
532 public static World get() {
533 return WORLD;
534 }
535
536 public static void cancelTask(Object attachment) {
537 cancelTask(attachment, false);
538 }
539
540 public static void cancelTask(Object attachment, boolean logout) {
541 get().taskManager.cancel(attachment, logout);
542 }
543
544 public static MobList<Player> getPlayers() {
545 return get().players;
546 }
547
548 public static MobList<Npc> getNpcs() {
549 return get().npcs;
550 }
551
552 public static RegionManager getRegions() {
553 return get().regionManager;
554 }
555
557 return taskManager;
558 }
559
560 public Queue<Player> getLogins() {
561 return logins;
562 }
563
564 public Queue<Player> getLogouts() {
565 return logouts;
566 }
567
568 public static DataBus getDataBus() {
569 return dataBus;
570 }
571
572}
The class that contains setting-related constants for the server.
Definition Config.java:24
static final int LOGIN_THESHOLD
The amount of players that can be logged in, in a single cycle.
Definition Config.java:160
static final int MAX_NPCS
The maximum amount of npcs that can be held within the game world.
Definition Config.java:169
static final int LOGOUT_THESHOLD
The amount of players that can logout in a single cycle.
Definition Config.java:163
static final int MAX_PLAYERS
The maximum amount of players that can be held within the game world.
Definition Config.java:166
A PestControlLobby manages all the PestControlGame that are active.
static void sequence()
Sequences all the active PestControlGame.
static final AtomicInteger BOT_COUNT
The repository containing all the clans and their corresponding data.
static void saveRecentHistory()
static void saveAllItemHistory()
Represents a single graphic that can be used by entities.
Definition Graphic.java:10
static DataBus getInstance()
Gets the singleton object.
Definition DataBus.java:52
A game representing a cyclic unit of work.
Definition Task.java:11
The class that handles scheduling tasks, and processing them.
static final AtomicBoolean update
Definition World.java:72
static Optional< Player > getPlayerBySlot(int index)
Gets a player by index.
Definition World.java:200
static void sendProjectile(Position source, Mob target, Projectile projectile)
Definition World.java:324
static final World WORLD
The world instance.
Definition World.java:80
static void sendProjectile(Position source, Position target, Projectile projectile)
Definition World.java:354
static void kickPlayer(Predicate< Player > condition)
Definition World.java:222
final RegionManager regionManager
The region manager.
Definition World.java:70
static void kickPlayer(Player other)
Definition World.java:217
static void schedule(Task task)
Submits a new event.
Definition World.java:247
static final Logger logger
Definition World.java:48
final TaskManager taskManager
The task manager.
Definition World.java:63
static void shutdown()
Shuts down the server.
Definition World.java:122
final MobList< Player > players
The players registered in this world.
Definition World.java:51
static int getPlayerCount()
Gets the amount of valid players online.
Definition World.java:490
static void sendProjectile(Mob source, Mob target, Projectile projectile)
Sends a world projectile.
Definition World.java:307
static void sendStaffMessage(String... messages)
Definition World.java:413
static void sendGraphic(Graphic graphic, Position position, int instance)
Sends a graphic to the world.
Definition World.java:268
final Queue< Player > logouts
The Players waiting to onLogout.
Definition World.java:60
static void sendProjectile(Projectile projectile, Position position, int instance, int lock, byte offsetX, byte offsetY)
Sends a world projectile.
Definition World.java:295
static void schedule(Runnable runnable)
Executes a runnable on a 1 tick delay.
Definition World.java:263
static void sendBroadcast(int time, String message, boolean countdown)
Sends a game message.
Definition World.java:420
TaskManager getTaskManager()
Definition World.java:556
static Optional< Player > search(String name)
Gets a player by name.
Definition World.java:147
static void sendProjectile(Mob source, Position target, Projectile projectile)
Sends a world projectile.
Definition World.java:340
void sequence()
Handles the world sequencing.
Definition World.java:92
static void cancelTask(Object attachment)
Definition World.java:536
Queue< Player > getLogouts()
Definition World.java:564
static Optional< Player > getPlayerByHash(long usernameHash)
Definition World.java:183
static void schedule(int delay, Runnable runnable)
Executes a runnable on a delay.
Definition World.java:252
static MobList< Npc > getNpcs()
Definition World.java:548
final MobList< Npc > npcs
The npcs registered in this world.
Definition World.java:54
static int executeProjectile(Mob entity, ProjectileTest projectile)
Definition World.java:366
static Optional< Npc > getNpcBySlot(int index)
Gets an npc by index.
Definition World.java:209
static void queueLogin(Player player)
Handles queueing the player logins.
Definition World.java:129
static void sendMessage(String... messages)
Sends a global message.
Definition World.java:396
Queue< Player > getLogins()
Definition World.java:560
static final DataBus dataBus
Definition World.java:77
static void sendGraphic(Graphic graphic, Position position)
Definition World.java:277
static DataBus getDataBus()
Definition World.java:568
final Thread taskDeadlockWatcherThread
The thread to watch task deadlocks on.
Definition World.java:68
static void update(int time)
Updates the server.
Definition World.java:113
final TaskDeadlockWatcher taskDeadlockWatcher
The task deadlock watcher relies on the TaskManager.
Definition World.java:65
static Optional< Player > searchAll(String name)
Definition World.java:160
static void cancelTask(Object attachment, boolean logout)
Definition World.java:540
static Optional< Player > getPlayerByName(String username)
Definition World.java:191
static MobList< Player > getPlayers()
Definition World.java:544
static void save()
Saves all the game data.
Definition World.java:97
final Queue< Player > logins
The Players waiting to login.
Definition World.java:57
static RegionManager getRegions()
Definition World.java:552
static void sendKillFeed(final Mob killer, final Mob victim)
Sends a kill feed notification.
Definition World.java:474
static void queueLogout(Player player)
Handles queueing the player logouts.
Definition World.java:138
static void sendMessage(String message, Predicate< Player > filter)
Sends a global message with an exception.
Definition World.java:405
static List< Player > getStaff()
Gets the staff players currently online.
Definition World.java:521
static void sendObjectAnimation(int animation, GameObject object)
Sends a world object animation.
Definition World.java:284
static int getWildernessCount()
Definition World.java:509
An Iterable implementation acting as a repository that holds instances of Entitys.
Definition MobList.java:26
Handles the mob class.
Definition Mob.java:66
final boolean isNpc()
Check if an entity is an npc.
Definition Mob.java:550
Represents a non-player character in the in-game world.
Definition Npc.java:29
This class represents a character controlled by a player.
Definition Player.java:125
void register()
Registers an entity to the World.
Definition Player.java:577
Handles checking if mobs are in a certain area.
Definition Area.java:13
static boolean inWilderness(Position position)
Definition Area.java:272
static boolean inWildernessResource(Interactable entity)
Definition Area.java:175
Represents a single tile on the game world.
Definition Position.java:14
Position getDelta(Position location, Position other)
int getY()
Gets the absolute y coordinate.
Definition Position.java:46
boolean isViewableFrom(Position other)
int getX()
Gets the absolute x coordinate.
Definition Position.java:41
Represents a single region.
Definition Region.java:21
The OutgoingPacket responsible for sending game messages.
The OutgoingPacket that sends a message to a Players chatbox in the client.
Created by Daniel on 2017-11-05.
Handles miscellaneous methods.
Definition Utility.java:27
static String capitalizeSentence(final String string)
Capitalize each letter after .
Definition Utility.java:99
static boolean withinDistance(Interactable source, Interactable target, int radius)
Definition Utility.java:470
static boolean isModerator(Player player)
Checks if the player is a management member.