RuneHive-Tarnish
Neural OSRS Enhancement Framework
Loading...
Searching...
No Matches
World.java
1package com.osroyale.game.world;
2
3import com.osroyale.Config;
4import com.osroyale.content.activity.impl.pestcontrol.PestControlLobby;
5import com.osroyale.content.bot.PlayerBot;
6import com.osroyale.content.clanchannel.ClanRepository;
7import com.osroyale.content.tradingpost.TradingPost;
8import com.osroyale.game.Graphic;
9import com.osroyale.game.Projectile;
10import com.osroyale.game.ProjectileTest;
11import com.osroyale.game.event.bus.DataBus;
12import com.osroyale.game.event.listener.WorldEventListener;
13import com.osroyale.game.task.Task;
14import com.osroyale.game.task.TaskDeadlockWatcher;
15import com.osroyale.game.task.TaskManager;
16import com.osroyale.game.task.impl.PlayerRemovalTask;
17import com.osroyale.game.task.impl.SystemUpdateEvent;
18import com.osroyale.game.world.entity.MobList;
19import com.osroyale.game.world.entity.mob.Mob;
20import com.osroyale.game.world.entity.mob.npc.Npc;
21import com.osroyale.game.world.entity.mob.player.Player;
22import com.osroyale.game.world.entity.mob.player.PlayerRight;
23import com.osroyale.game.world.entity.mob.player.persist.PlayerSerializer;
24import com.osroyale.game.world.object.GameObject;
25import com.osroyale.game.world.position.Area;
26import com.osroyale.game.world.position.Position;
27import com.osroyale.game.world.region.Region;
28import com.osroyale.game.world.region.RegionManager;
29import com.osroyale.net.packet.out.*;
30import com.osroyale.util.GameSaver;
31import com.osroyale.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
82
83public final class World {
84
85 private static final Logger logger = LogManager.getLogger(World.class);
86
88 private final MobList<Player> players = new MobList<>(Config.MAX_PLAYERS);
89
91 private final MobList<Npc> npcs = new MobList<>(Config.MAX_NPCS);
92
94 private final Queue<Player> logins = new ConcurrentLinkedQueue<>();
95
97 private final Queue<Player> logouts = new ConcurrentLinkedQueue<>();
98
100 private final TaskManager taskManager;
102 private final TaskDeadlockWatcher taskDeadlockWatcher;
103
105 private final Thread taskDeadlockWatcherThread;
107 private final RegionManager regionManager = new RegionManager();
108
109 public static final AtomicBoolean update = new AtomicBoolean(false);
110
111 public static int addition = 0;
112
113
114 private static final DataBus dataBus = DataBus.getInstance();
115
117 private static final World WORLD = new World();
118
119 private World() {
120 dataBus.subscribe(new WorldEventListener());
121 taskManager = new TaskManager();
122 taskDeadlockWatcher = new TaskDeadlockWatcher(taskManager);
123 taskDeadlockWatcherThread = new Thread(taskDeadlockWatcher);
124 taskDeadlockWatcherThread.setName("TaskDeadlockWatcher");
125 taskDeadlockWatcherThread.start();
126 }
127
129 public void sequence() {
130
131 }
132
134 public static void save() {
135 System.out.println("Saving Tarnish...");
136 get().players.forEach(PlayerSerializer::save);
137 logger.info("All players were successfully saved.");
138 /* GlobalRecords.save();
139 logger.info("All global records were successfully saved.");*/
140 ClanRepository.saveAllActiveClans();
141 logger.info("All clans were successfully saved.");
142 TradingPost.saveRecentHistory();
143 TradingPost.saveAllItemHistory();
144 logger.info("All trading post history was successfully saved");
145 GameSaver.save();
146 logger.info("All game data were successfully saved.");
147 }
148
150 public static void update(int time) {
151 if (!update.get()) {
152 update.set(true);
153 schedule(new SystemUpdateEvent(time));
154 get().players.stream().forEach(it -> it.send(new SendGameMessage(0, time / 100, "System update" + " in:")));
155 }
156 }
157
159 public static void shutdown() {
160 System.out.println("shutting down...");
161 get().taskDeadlockWatcher.requestExit();
162 System.exit(0);
163 }
164
166 public static void queueLogin(Player player) {
167 if (player.isBot) {
168 get().logins.add(player);
169 } else {
170 player.getSession().ifPresent(it -> World.get().logins.add(player));
171 }
172 }
173
175 public static void queueLogout(Player player) {
176 if (player == null || get().logouts.contains(player)) {
177 return;
178 }
179
180 get().logouts.add(player);
181 }
182
184 public static Optional<Player> search(String name) {
185 for (Player player : get().players) {
186 if (player == null) {
187 continue;
188 }
189
190 if (player.getUsername().equalsIgnoreCase(name)) {
191 return Optional.of(player);
192 }
193 }
194 return Optional.empty();
195 }
196
197 public static Optional<Player> searchAll(String name) {
198 for (Player player : get().players) {
199 if (player == null) {
200 continue;
201 }
202
203 if (player.getUsername().equalsIgnoreCase(name)) {
204 return Optional.of(player);
205 }
206 }
207
208 for (Player player : World.get().getLogins()) {
209 if (player == null) {
210 continue;
211 }
212
213 if (player.getUsername().equalsIgnoreCase(name)) {
214 return Optional.of(player);
215 }
216 }
217 return Optional.empty();
218 }
219
220 public static Optional<Player> getPlayerByHash(long usernameHash) {
221 for (Player player : World.getPlayers()) {
222 if (Objects.equals(player.usernameLong, usernameHash))
223 return Optional.of(player);
224 }
225 return Optional.empty();
226 }
227
228 public static Optional<Player> getPlayerByName(String username) {
229 for (Player player : World.getPlayers()) {
230 if (Objects.equals(player.getUsername(), username))
231 return Optional.of(player);
232 }
233 return Optional.empty();
234 }
235
237 public static Optional<Player> getPlayerBySlot(int index) {
238 for (Player player : World.getPlayers()) {
239 if (player.getIndex() == index)
240 return Optional.of(player);
241 }
242 return Optional.empty();
243 }
244
246 public static Optional<Npc> getNpcBySlot(int index) {
247 for (Npc npc : World.getNpcs()) {
248 if (npc.getIndex() == index)
249 return Optional.of(npc);
250 }
251 return Optional.empty();
252 }
253
254 public static void kickPlayer(Player other) {
255 other.send(new SendLogout());
256 queueLogout(other);
257 }
258
259 public static void kickPlayer(Predicate<Player> condition) {
260 for (Player player : get().players) {
261 if (player.isBot)
262 continue;
263 if (!condition.test(player))
264 continue;
265 player.send(new SendLogout());
266 queueLogout(player);
267 }
268 }
269
270 public void process() {
271 try {
272 taskManager.processTasks();
273 } catch (Exception ex) {
274 logger.error("Error sequencing task manager", ex);
275 }
276 try {
277 PestControlLobby.sequence();
278 } catch (Exception ex) {
279 logger.error("Error sequencing pest control.", ex);
280 }
281 }
282
284 public static void schedule(Task task) {
285 get().taskManager.schedule(task);
286 }
287
289 public static void schedule(int delay, Runnable runnable) {
290 schedule(new Task(delay) {
291 @Override
292 public void execute() {
293 runnable.run();
294 cancel();
295 }
296 });
297 }
298
300 public static void schedule(Runnable runnable) {
301 schedule(1, runnable);
302 }
303
305 public static void sendGraphic(Graphic graphic, Position position, int instance) {
306 for (Player player : getPlayers()) {
307 if (player.instance != instance)
308 continue;
309 if (!Utility.withinDistance(player, position, Region.VIEW_DISTANCE))
310 continue;
311 player.send(new SendGraphic(graphic, position));
312 }
313 }
314 public static void sendGraphic(Graphic graphic, Position position) {
315 get().players.stream().filter(player -> Utility.withinDistance(player, position, Region.VIEW_DISTANCE))
316 .forEach(player -> {
317 player.send(new SendGraphic(graphic, position));
318 });
319 }
321 public static void sendObjectAnimation(int animation, GameObject object) {
322 for (Player player : getPlayers()) {
323 if (player.instance != object.getInstancedHeight())
324 continue;
325 if (!Utility.withinDistance(player, object.getPosition(), Region.VIEW_DISTANCE))
326 continue;
327 player.send(new SendObjectAnimation(animation, object));
328 }
329 }
330
332 public static void sendProjectile(Projectile projectile, Position position, int instance, int lock, byte offsetX, byte offsetY) {
333 for (Player player : getPlayers()) {
334 if (player.instance != instance)
335 continue;
336 if (!Utility.withinDistance(player, position, Region.VIEW_DISTANCE))
337 continue;
338 player.send(new SendProjectile(projectile, position, lock, offsetX, offsetY));
339
340 }
341 }
342
344 public static void sendProjectile(Mob source, Mob target, Projectile projectile) {
345 int lockon = target.isNpc() ? target.getIndex() + 1 : -target.getIndex() - 1;
346 int sourceX = source.getX() + source.width() / 2, sourceY = source.getY() + source.length() / 2;
347 int targetX = target.getX() + target.width() / 2, targetY = target.getY() + target.length() / 2;
348 byte offsetX = (byte) (targetX - sourceX);
349 byte offsetY = (byte) (targetY - sourceY);
350 Position center = new Position(sourceX, sourceY);
351
352 for (Player player : getPlayers()) {
353 if (source.instance != player.instance)
354 continue;
355 if (!Utility.withinDistance(target, player, Region.VIEW_DISTANCE))
356 continue;
357 player.send(new SendProjectile(projectile, center, lockon, offsetX, offsetY));
358 }
359 }
360
361 public static void sendProjectile(Position source, Mob target, Projectile projectile) {
362 int lockon = target.isNpc() ? target.getIndex() + 1 : -target.getIndex() - 1;
363 int sourceX = source.getX(), sourceY = source.getY();
364 int targetX = target.getX() + target.width() / 2, targetY = target.getY() + target.length() / 2;
365 byte offsetX = (byte) (targetX - sourceX);
366 byte offsetY = (byte) (targetY - sourceY);
367 Position center = new Position(sourceX, sourceY);
368
369 for (Player player : getPlayers()) {
370 if (!Utility.withinDistance(target, player, Region.VIEW_DISTANCE))
371 continue;
372 player.send(new SendProjectile(projectile, center, lockon, offsetX, offsetY));
373 }
374 }
375
377 public static void sendProjectile(Mob source, Position target, Projectile projectile) {
378 int sourceX = source.getX() + source.width() / 2, sourceY = source.getY() + source.length() / 2;
379 Position center = new Position(sourceX, sourceY);
380 byte offsetX = (byte) (target.getX() - sourceX);
381 byte offsetY = (byte) (target.getY() - sourceY);
382 for (Player player : getPlayers()) {
383 if (source.instance != player.instance)
384 continue;
385 if (!Utility.withinDistance(player, target, Region.VIEW_DISTANCE))
386 continue;
387 player.send(new SendProjectile(projectile, center, -1, offsetX, offsetY));
388 }
389 }
390
391 public static void sendProjectile(Position source, Position target, Projectile projectile) {
392 int sourceX = source.getX(), sourceY = source.getY();
393 Position center = new Position(sourceX, sourceY);
394 byte offsetX = (byte) (target.getX() - sourceX);
395 byte offsetY = (byte) (target.getY() - sourceY);
396 for (Player player : getPlayers()) {
397 if (!Utility.withinDistance(player, target, Region.VIEW_DISTANCE))
398 continue;
399 player.send(new SendProjectile(projectile, center, -1, offsetX, offsetY));
400 }
401 }
402
403 public static int executeProjectile(Mob entity, ProjectileTest projectile) {
404 if (projectile == null) {
405 return 0;
406 }
407 Position source = projectile.getStart();
408 Position target = projectile.getTarget();
409 if (source == null || target == null) {
410 return 0;
411 }
412 Position delta = projectile.getTarget().getDelta(source, target);
413
414 int distance = entity.getPosition().getChevDistance(target);
415
416 if (distance <= 60) {
417 int creatorSize = projectile.getCreatorSize() == -1 ? 1 : projectile.getCreatorSize(); //TODO size
418
419 for (Player player : getPlayers()) {
420 if (player == null) {
421 continue;
422 }
423
424 if (source.isViewableFrom(player.getPosition())) {
425 player.send(new SendProjectileTestPacket(source, delta, projectile.getSlope(), projectile.getSpeed(), projectile.getProjectileId(), projectile.getStartHeight(), projectile.getEndHeight(), projectile.getLockon(), projectile.getDelay(), creatorSize, projectile.getStartDistanceOffset()));
426 }
427 }
428 }
429 return projectile.getHitDelay(distance);
430 }
431
433 public static void sendMessage(String... messages) {
434 for (Player player : getPlayers()) {
435 if (player != null)
436 player.message(messages);
437 }
438 }
439
441 public static void sendMessage(String message, Predicate<Player> filter) {
442 for (Player player : getPlayers()) {
443 if (player != null && filter.test(player))
444 player.message(message);
445 }
446 }
447
448 public static void sendStaffMessage(String... messages) {
449 for (Player player : getStaff()) {
450 player.message(messages);
451 }
452 }
453
455 public static void sendBroadcast(int time, String message, boolean countdown) {
456 get().players.stream().forEach($it -> {
457 $it.send(new SendGameMessage(countdown ? 0 : 1, time, Utility.capitalizeSentence(message)));
458 $it.send(new SendMessage("<col=2C7526>Broadcast: </col>" + Utility.capitalizeSentence(message)));
459 });
460 }
461
462 public void dequeLogins() {
463 if (logins.isEmpty()) {
464 return;
465 }
466
467 for (int index = 0; index < Config.LOGIN_THESHOLD; index++) {
468 Player player = logins.poll();
469
470 if (player == null) {
471 break;
472 }
473
474 try {
475 player.register();
476 } catch (Exception ex) {
477 logger.error(String.format("error registering %s", player), ex);
478 }
479
480 }
481 }
482
483 public void dequeLogouts() {
484 if (logouts.isEmpty()) {
485 return;
486 }
487
488 for (int index = 0; index < Config.LOGOUT_THESHOLD; index++) {
489 Player player = logouts.poll();
490
491 if (player == null) {
492 break;
493 }
494
495 World.schedule(new PlayerRemovalTask(player, false));
496 }
497 }
498
499 public int getWildernessResourcePlayers() {
500 int count = 0;
501 for (Player player : getPlayers()) {
502 if (player != null && Area.inWildernessResource(player))
503 count++;
504 }
505 return count;
506 }
507
509 public static void sendKillFeed(final Mob killer, final Mob victim) {
510 if (victim.isNpc()) {
511 if (Area.inWilderness(victim)) {
512 return;
513 }
514 if (!victim.getNpc().npcAssistant.isBoss()) {
515 return;
516 }
517 }
518
519 for (final Player player : getPlayers()) {
520 player.send(new SendKillFeed(killer, victim));
521 }
522 }
523
525 public static int getPlayerCount() {
526 return Math.toIntExact(getPlayers().size() + addition);
527 }
528
529 public static int getBotCount() {
530 return PlayerBot.BOT_COUNT.get();
531 }
532
533 public static int getStaffCount() {
534 int count = 0;
535
536 for (Player player : getPlayers()) {
537 if (player != null && (PlayerRight.isModerator(player) || player.right == PlayerRight.HELPER))
538 count++;
539 }
540
541 return count;
542 }
543
544 public static int getWildernessCount() {
545 int count = 0;
546
547 for (Player player : getPlayers()) {
548 if (player != null && !player.isBot && Area.inWilderness(player))
549 count++;
550 }
551
552 return count;
553 }
554
556 public static List<Player> getStaff() {
557 List<Player> staff = new ArrayList<>();
558
559 for (Player player : getPlayers()) {
560 if (player != null && (PlayerRight.isModerator(player) || player.right == PlayerRight.HELPER))
561 staff.add(player);
562 }
563
564 return staff;
565 }
566
567 public static World get() {
568 return WORLD;
569 }
570
571 public static void cancelTask(Object attachment) {
572 cancelTask(attachment, false);
573 }
574
575 public static void cancelTask(Object attachment, boolean logout) {
576 get().taskManager.cancel(attachment, logout);
577 }
578
579 public static MobList<Player> getPlayers() {
580 return get().players;
581 }
582
583 public static MobList<Npc> getNpcs() {
584 return get().npcs;
585 }
586
587 public static RegionManager getRegions() {
588 return get().regionManager;
589 }
590
591 public TaskManager getTaskManager() {
592 return taskManager;
593 }
594
595 public Queue<Player> getLogins() {
596 return logins;
597 }
598
599 public Queue<Player> getLogouts() {
600 return logouts;
601 }
602
603 public static DataBus getDataBus() {
604 return dataBus;
605 }
606
607}
static final int MAX_NPCS
Definition Config.java:207
static final int LOGIN_THESHOLD
Definition Config.java:198
static final int MAX_PLAYERS
Definition Config.java:204
void cancel(Object attachment)
static void update(int time)
Definition World.java:150
static void sendObjectAnimation(int animation, GameObject object)
Definition World.java:321
static Optional< Player > getPlayerBySlot(int index)
Definition World.java:237
static void sendKillFeed(final Mob killer, final Mob victim)
Definition World.java:509
static void sendProjectile(Mob source, Position target, Projectile projectile)
Definition World.java:377
static void sendMessage(String message, Predicate< Player > filter)
Definition World.java:441
static List< Player > getStaff()
Definition World.java:556
static void sendGraphic(Graphic graphic, Position position, int instance)
Definition World.java:305
static void sendMessage(String... messages)
Definition World.java:433
static Optional< Player > search(String name)
Definition World.java:184
static void schedule(Task task)
Definition World.java:284
static void queueLogout(Player player)
Definition World.java:175
static void sendBroadcast(int time, String message, boolean countdown)
Definition World.java:455
static void queueLogin(Player player)
Definition World.java:166
static void sendProjectile(Mob source, Mob target, Projectile projectile)
Definition World.java:344
static void schedule(int delay, Runnable runnable)
Definition World.java:289
static void sendProjectile(Projectile projectile, Position position, int instance, int lock, byte offsetX, byte offsetY)
Definition World.java:332
static Optional< Npc > getNpcBySlot(int index)
Definition World.java:246
static void schedule(Runnable runnable)
Definition World.java:300
static String capitalizeSentence(final String string)
Definition Utility.java:136