1package com.runehive.util;
3import com.runehive.RuneHive;
4import com.runehive.game.world.Interactable;
5import com.runehive.game.world.entity.mob.Direction;
6import com.runehive.game.world.entity.mob.Mob;
7import com.runehive.game.world.entity.mob.player.Player;
8import com.runehive.game.world.entity.skill.Skill;
9import com.runehive.game.world.pathfinding.TraversalMap;
10import com.runehive.game.world.pathfinding.path.Path;
11import com.runehive.game.world.position.Position;
12import com.runehive.net.packet.out.SendMessage;
15import java.lang.reflect.InvocationTargetException;
16import java.text.NumberFormat;
17import java.text.SimpleDateFormat;
19import java.util.stream.Collectors;
20import java.util.stream.Stream;
30 private static final Random
RANDOM =
new Random(System.currentTimeMillis());
33 private static final char[]
VALID_CHARS = {
'_',
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'/'};
37 return 100D * progress / total;
42 return NumberFormat.getInstance().format(amount);
47 return NumberFormat.getInstance().format(amount);
52 return NumberFormat.getInstance().format(amount);
57 if (amount >= 0 && amount < 1_000)
59 if (amount >= 1_000 && amount < 1_000_000) {
60 return (amount / 1_000) +
"K";
62 if (amount >= 1_000_000 && amount < 1_000_000_000) {
63 return (amount / 1_000_000) +
"M";
65 if (amount >= 1_000_000_000 && amount < Integer.MAX_VALUE) {
66 return (amount / 1_000_000_000) +
"B";
68 return "<col=fc2a2a>Lots!";
73 for (
int i = 0; i <
string.length() && i < 12; i++) {
74 char c =
string.charAt(i);
76 if (c >=
'A' && c <=
'Z')
78 else if (c >=
'a' && c <=
'z')
80 else if (c >=
'0' && c <=
'9')
83 while (l % 37L == 0L && l != 0L)
94 public static String
rank(
final String
string) {
95 return Stream.of(
string.trim().split(
"\\s")).filter(word -> word.length() > 0).map(word -> word.substring(0, 1).toUpperCase() + word.substring(1)).collect(Collectors.joining(
" "));
101 boolean capitalize =
true;
102 StringBuilder sb =
new StringBuilder(
string);
103 while (pos < sb.length()) {
104 if (sb.charAt(pos) ==
'.') {
106 }
else if (capitalize && !Character.isWhitespace(sb.charAt(pos))) {
107 sb.setCharAt(pos, Character.toUpperCase(sb.charAt(pos)));
112 return sb.toString();
118 char c = nextWord.toUpperCase().charAt(0);
119 if (c ==
'A' || c ==
'E' || c ==
'I' || c ==
'O' || c ==
'U') {
127 return new SimpleDateFormat(
"EE MMM dd yyyy").format(
new Date());
132 return new SimpleDateFormat(
"yyyy/MM/dd").format(
new Date());
142 return new SimpleDateFormat(
"hh:mm aa").format(
new Date());
147 return new SimpleDateFormat(
"m:ss").format(period);
151 return new SimpleDateFormat(
"HH:mm:ss").format(period);
161 long secs = ticks * 3 / 5;
164 return "0:" + (secs < 10 ?
"0" :
"") + secs;
167 long mins = secs / 60;
168 long remainderSecs = secs - (mins * 60);
170 return mins +
":" + (remainderSecs < 10 ?
"0" :
"") + remainderSecs +
"";
173 long hours = mins / 60;
174 long remainderMins = mins - (hours * 60);
176 return hours +
"h " + (remainderMins < 10 ?
"0" :
"") + remainderMins +
"m " + (remainderSecs < 10 ?
"0" :
"") + remainderSecs +
"s";
179 long days = hours / 24;
180 long remainderHrs = hours - (days * 24);
181 return days +
"d " + (remainderHrs < 10 ?
"0" :
"") + remainderHrs +
"h " + (remainderMins < 10 ?
"0" :
"") + remainderMins +
"m";
187 for (
int index = 0; index < text.length() && index < 12; index++) {
188 char key = text.charAt(index);
190 if (key >=
'A' && key <=
'Z')
191 hash += (1 + key) - 65;
192 else if (key >=
'a' && key <=
'z')
193 hash += (1 + key) - 97;
194 else if (key >=
'0' && key <=
'9')
195 hash += (27 + key) - 48;
197 while (
hash % 37L == 0L &&
hash != 0L)
203 if (l <= 0L || l >= 0x5b5b57f8a98a5dd1L)
208 char ac[] =
new char[12];
214 return new String(ac, 12 - i, i);
217 public static long hash(String input) {
222 for (
int index = 0; index < input.length() && index < 12; index++) {
223 char key = input.charAt(index);
225 if (key >=
'A' && key <=
'Z') {
226 hash += (1 + key) - 65;
227 }
else if (key >=
'a' && key <=
'z') {
228 hash += (1 + key) - 97;
229 }
else if (key >=
'0' && key <=
'9') {
230 hash += (27 + key) - 48;
233 while (
hash % 37L == 0L &&
hash != 0L) {
240 return random(0, bound,
false);
243 public static int random(
int lowerBound,
int upperBound) {
244 return random(lowerBound, upperBound,
false);
249 return new ArrayList<T>(collection).get((
int) (
RANDOM.nextDouble() * collection.size()));
254 return list.get((
int) (
RANDOM.nextDouble() * list.size()));
267 return array[(int) (
RANDOM.nextDouble() * array.length)];
272 return array[(int) (
RANDOM.nextDouble() * array.length)];
275 public static int random(
int lowerBound,
int upperBound,
boolean inclusive) {
276 if (lowerBound >= upperBound) {
277 throw new IllegalArgumentException(
"The lower bound cannot be larger than or equal to the upper bound!");
280 return lowerBound +
RANDOM.nextInt(upperBound - lowerBound) + (inclusive ? 1 : 0);
285 List<Object> classes =
new LinkedList<>();
286 File dir =
new File(directory);
287 if (!dir.exists() || !dir.isDirectory()) {
291 File[] files = dir.listFiles();
295 for (File f : files) {
296 if (f.isDirectory() || f.getName().contains(
"$")) {
299 String domainPath =
Utility.class.getProtectionDomain().getCodeSource().getLocation().getPath().replace(
"/",
"\\");
300 String filePath =
"\\" + f.getPath();
301 String clazzName = filePath.replace(domainPath,
"");
302 clazzName = clazzName.replace(
"\\",
".");
303 clazzName = clazzName.replace(
".class",
"");
304 Class<?> clazz = Class.forName(clazzName);
305 Object o = clazz.getDeclaredConstructor().newInstance();
308 }
catch (ClassNotFoundException | IllegalAccessException | InstantiationException
309 | InvocationTargetException | NoSuchMethodException e) {
317 String filePath = clazz.getResource(
"/" + clazz.getName().replace(
".",
"/") +
".class").getFile();
318 File file =
new File(filePath);
319 File directory = file.getParentFile();
320 List<String> list =
new ArrayList<>();
322 File[] files = directory.listFiles();
325 return Collections.emptyList();
328 for (File f : files) {
329 if (f.isDirectory()) {
330 list.add(f.getPath());
334 String[] directories = list.toArray(
new String[0]);
335 return Arrays.asList(directories);
346 boolean changed =
false;
350 }
else if (diffX >= 88) {
356 }
else if (diffY >= 88) {
368 if (sourceTopRight.
getX() < target.
getX()) {
369 dx = target.
getX() - sourceTopRight.
getX();
370 }
else if (source.
getX() > target.
getX()) {
376 if (sourceTopRight.
getY() < target.
getY()) {
377 dy = target.
getY() - sourceTopRight.
getY();
378 }
else if (source.
getY() > target.
getY()) {
389 return Integer.MAX_VALUE;
392 if (sourceWidth <= 0) sourceWidth = 1;
393 if (sourceLength <= 0) sourceLength = 1;
394 if (targetWidth <= 0) targetWidth = 1;
395 if (targetLength <= 0) targetLength = 1;
397 Position sourceTopRight = source.
transform(sourceWidth - 1, sourceLength - 1, 0);
398 Position targetTopRight = target.
transform(targetWidth - 1, targetLength - 1, 0);
402 if (sourceTopRight.
getX() < target.
getX()) {
403 dx = target.
getX() - sourceTopRight.
getX();
404 }
else if (source.
getX() > targetTopRight.
getX()) {
405 dx = source.
getX() - targetTopRight.
getX();
410 if (sourceTopRight.
getY() < target.
getY()) {
411 dy = target.
getY() - sourceTopRight.
getY();
412 }
else if (source.
getY() > targetTopRight.
getY()) {
413 dy = source.
getY() - targetTopRight.
getY();
426 if (sourceWidth <= 0) sourceWidth = 1;
427 if (sourceLength <= 0) sourceLength = 1;
428 if (targetWidth <= 0) targetWidth = 1;
429 if (targetLength <= 0) targetLength = 1;
431 Position sourceTopRight = source.
transform(sourceWidth - 1, sourceLength - 1, 0);
432 Position targetTopRight = target.
transform(targetWidth - 1, targetLength - 1, 0);
436 if (sourceTopRight.
getX() < target.
getX()) {
437 dx = target.
getX() - sourceTopRight.
getX();
438 }
else if (source.
getX() > targetTopRight.
getX()) {
439 dx = source.
getX() - targetTopRight.
getX();
444 if (sourceTopRight.
getY() < target.
getY()) {
445 dy = target.
getY() - sourceTopRight.
getY();
446 }
else if (source.
getY() > targetTopRight.
getY()) {
447 dy = source.
getY() - targetTopRight.
getY();
464 int dx = target.
getX() - source.
getX();
465 int dy = target.
getY() - source.
getY();
471 return within(source, target, radius);
503 int dx, dy, dist = Integer.MAX_VALUE;
506 for (
int x = 0; x < target.
width(); x++) {
510 if (dist > distance) {
518 if (dist > distance) {
524 for (
int y = 0; y < target.
length(); y++) {
528 if (dist > distance) {
536 if (dist > distance) {
551 }
else if (sourceTopRight.
getX() < best.
getX()) {
552 dx = best.
getX() - sourceTopRight.
getX();
558 }
else if (sourceTopRight.
getY() < best.
getY()) {
559 dy = best.
getY() - sourceTopRight.
getY();
570 List<Position> boundaries =
new LinkedList<>();
571 Map<Position, LinkedList<Position>> paths =
new HashMap<>();
576 int dx = Integer.signum(delta.
getX()), dy = Integer.signum(delta.
getY());
588 LinkedList<Position> list = paths.computeIfAbsent(position, pos -> {
589 boundaries.add(position);
590 return new LinkedList<>();
594 paths.put(position, list);
598 if (boundaries.isEmpty())
return;
607 int width = interactable.
width();
608 int length = interactable.
length();
610 for (
int y = 0; y < length + 2; y++) {
611 for (
int x = 0; x < width + 2; x++) {
612 int xx = x % (width + 1);
613 int yy = y % (length + 1);
614 if (xx == 0 && yy == 0 || xx != 0 && yy != 0)
continue;
624 for (
int y = 0; y < length; y++) {
625 for (
int x = 0; x < width; x++) {
626 boundaries[nextSlot++] = position.
transform(x, y, 0);
634 int width = interactable.
width();
635 int length = interactable.
length();
637 for (
int y = 0; y < length; y++) {
638 for (
int x = 0; x < width; x++) {
650 StringBuilder formattedName =
new StringBuilder();
653 String[] words = input.trim().split(
" ");
656 for (String word : words) {
657 if (!word.isEmpty()) {
659 char firstLetter = Character.toUpperCase(word.charAt(0));
660 formattedName.append(firstLetter);
663 if (word.length() > 1) {
664 formattedName.append(word.substring(1));
668 formattedName.append(
" ");
673 return formattedName.toString().trim();
679 return within(interactableSource, interactableTarget, distance);
683 for (
int i = 0; i < s.length(); i++) {
685 s = String.format(
"%s%s", Character.toUpperCase(s.charAt(0)),
688 if (!Character.isLetterOrDigit(s.charAt(i))) {
689 if (i + 1 < s.length()) {
690 s = String.format(
"%s%s%s", s.subSequence(0, i + 1),
691 Character.toUpperCase(s.charAt(i + 1)),
696 return s.replace(
"_",
" ");
707 public static boolean withinOctal(
Position source,
int sourceWidth,
int sourceLength,
Position target,
int targetWidth,
int targetLength,
int distance) {
714 if (sourceTopRight.
getX() < target.
getX()) {
715 dx = Math.abs(target.
getX() - sourceTopRight.
getX());
716 }
else if (source.
getX() > targetTopRight.
getX()) {
717 dx = Math.abs(targetTopRight.
getX() - source.
getX());
721 if (sourceTopRight.
getY() < target.
getY()) {
722 dy = Math.abs(target.
getY() - sourceTopRight.
getY());
723 }
else if (source.
getY() > targetTopRight.
getY()) {
724 dy = Math.abs(targetTopRight.
getY() - source.
getY());
728 return dx <= distance && dy <= distance;
731 public static boolean within(
Position source,
int sourceWidth,
int sourceLength,
Position target,
int targetWidth,
int targetLength,
int distance) {
738 if (sourceTopRight.
getX() < target.
getX()) {
739 dx = Math.abs(target.
getX() - sourceTopRight.
getX());
740 }
else if (source.
getX() > targetTopRight.
getX()) {
741 dx = Math.abs(targetTopRight.
getX() - source.
getX());
745 if (sourceTopRight.
getY() < target.
getY()) {
746 dy = Math.abs(target.
getY() - sourceTopRight.
getY());
747 }
else if (source.
getY() > targetTopRight.
getY()) {
748 dy = Math.abs(targetTopRight.
getY() - source.
getY());
752 return dx + dy <= distance;
756 if (source ==
null || target ==
null) {
766 if (sourceTopRight.
getX() < target.
getX()) {
767 dx = Math.abs(target.
getX() - sourceTopRight.
getX());
768 }
else if (source.
getX() > targetTopRight.
getX()) {
769 dx = Math.abs(targetTopRight.
getX() - source.
getX());
773 if (sourceTopRight.
getY() < target.
getY()) {
774 dy = Math.abs(target.
getY() - sourceTopRight.
getY());
775 }
else if (source.
getY() > targetTopRight.
getY()) {
776 dy = Math.abs(targetTopRight.
getY() - source.
getY());
780 return dx <= radius && dy <= radius;
791 public static boolean inside(
Position source,
int sourceWidth,
int sourceLength,
Position target,
int targetWidth,
int targetLength) {
792 if (sourceWidth <= 0) sourceWidth = 1;
793 if (sourceLength <= 0) sourceLength = 1;
794 if (targetWidth <= 0) targetWidth = 1;
795 if (targetLength <= 0) targetLength = 1;
796 Position sourceTopRight = source.
transform(sourceWidth - 1, sourceLength - 1, 0);
797 Position targetTopRight = target.
transform(targetWidth - 1, targetLength - 1, 0);
798 if (source.
equals(target) || sourceTopRight.
equals(targetTopRight)) {
801 if (source.
getX() > targetTopRight.
getX() || sourceTopRight.
getX() < target.
getX()) {
804 return source.
getY() <= targetTopRight.
getY() && sourceTopRight.
getY() >= target.
getY();
809 for (
int index = 0; index < requirements.length; index++) {
811 int required = requirements[index];
813 if (level < required) {
828 File file =
new File(
"./data/starters/" + host +
".txt");
829 if (!file.exists()) {
832 BufferedReader in =
new BufferedReader(
new FileReader(file));
834 String whatever = in.readLine();
836 long max = Long.parseLong(whatever);
838 if (max > Integer.MAX_VALUE) {
845 }
catch (Exception e) {
862 }
else if (amount == 1) {
867 File file =
new File(
"./data/starters/" + host +
".txt");
868 BufferedWriter out =
new BufferedWriter(
new FileWriter(file,
false));
869 out.write(String.valueOf(amount));
871 }
catch (Exception e) {
879 int[] shuffledArray =
new int[array.length];
880 System.arraycopy(array, 0, shuffledArray, 0, array.length);
882 for (
int i = shuffledArray.length - 1; i > 0; i--) {
883 int index =
RANDOM.nextInt(i + 1);
884 int a = shuffledArray[index];
885 shuffledArray[index] = shuffledArray[i];
886 shuffledArray[i] = a;
888 return shuffledArray;
892 return Calendar.getInstance().get(Calendar.DAY_OF_YEAR);
895 public static int min(
int... values) {
896 int i = Integer.MAX_VALUE;
903 public static final boolean goodDistance(
int objectX,
int objectY,
int playerX,
int playerY,
int distance) {
904 int deltaX = objectX - playerX;
905 int deltaY = objectY - playerY;
906 int trueDistance = ((int) Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)));
907 return trueDistance <= distance;
910 public static boolean inRange(
int absX,
int absY,
int size,
int targetX,
int targetY,
int targetSize,
int distance) {
911 if (absX < targetX) {
915 int closestX = absX + (size - 1);
916 int diffX = targetX - closestX;
917 if (diffX > distance)
919 }
else if (absX > targetX) {
923 int closestTargetX = targetX + (targetSize - 1);
924 int diffX = absX - closestTargetX;
925 if (diffX > distance)
928 if (absY < targetY) {
932 int closestY = absY + (size - 1);
933 int diffY = targetY - closestY;
934 return diffY <= distance;
935 }
else if (absY > targetY) {
939 int closestTargetY = targetY + (targetSize - 1);
940 int diffY = absY - closestTargetY;
941 return diffY <= distance;
static final Stopwatch UPTIME
final SkillManager skills
void setFixingInside(boolean fixingInside)
boolean addPath(Path path)
Finds a smart path to the target.
This class represents a character controlled by a player.
void send(OutgoingPacket encoder)
Represents a trainable and usable skill.
static String getName(int skill)
Gets the name for a skill id.
int getMaxLevel(int id)
Gets the highest possible level of a skill.
Contains traversal data for a set of regions.
static boolean isTraversable(Position from, Direction direction, int size)
Tests whether or not a specified position is traversable in the specified direction.
Represents a single path in the path finding system.
Represents a single tile on the game world.
int getHeight()
Gets the height coordinate, or height.
int getY()
Gets the absolute y coordinate.
int getX()
Gets the absolute x coordinate.
Position transform(int diffX, int diffY, int diffZ)
Creates a new location based on this location.
boolean equals(Object obj)
static Position create(int x, int y, int z)
Creates a location.
int getChunkX()
Gets the chunk x coordinate.
int getChunkY()
Gets the chunk y coordinate.
The OutgoingPacket that sends a message to a Players chatbox in the client.
long elapsedTime(TimeUnit unit)
Handles miscellaneous methods.
static String formatName(final String input)
static String getTime(long period)
Gets the time based off a long.
static int random(int bound)
static int randomElement(int[] array)
Picks a random element out of any array type.
static long nameToLong(String text)
Converts the first 12 characters in a string of text to a hash.
static int getStarters(String host)
static boolean setStarter(Player player)
static String formatText(String s)
static boolean within(Position source, int sourceWidth, int sourceLength, Position target, int targetWidth, int targetLength, int distance)
static String longToString(long l)
static boolean hasOneOutOf(double chance)
static< T > T randomElement(T[] array)
Picks a random element out of any array type.
static Position findAccessableTile(Interactable source)
static String getTime(int ticks)
Gets a basic time based off seconds.
static final boolean goodDistance(int objectX, int objectY, int playerX, int playerY, int distance)
static boolean inRange(Interactable source, Interactable target, int distance)
static String capitalizeSentence(final String string)
Capitalize each letter after .
static long hash(String input)
static String formatDigits(final long amount)
Formats digits for longs.
static String getDate()
Gets the date of server.
static Position getDelta(Interactable source, Interactable target)
static boolean inside(Interactable source, Interactable target)
static List< String > getSubDirectories(Class<?> clazz)
Gets all of the sub directories of a folder.
static List< Object > getClassesInDirectory(String directory)
Gets all of the classes in a directory.
static int getDistance(Interactable source, Interactable target)
static String formatDigits(final int amount)
Formats digits for integers.
static double getPercentageAmount(int progress, int total)
Gets a percentage amount.
static String bigDaddyTime(long period)
static boolean inRange(int absX, int absY, int size, int targetX, int targetY, int targetSize, int distance)
static int getDistance(Interactable source, Position target)
static String formatDigits(final double amount)
Formats digits for doubles.
static Position findBestInside(Interactable source, Interactable target)
static boolean inside(Position source, int sourceWidth, int sourceLength, Position target, int targetWidth, int targetLength)
static< T > T randomElement(Collection< T > collection)
Picks a random element out of any array type.
static void fixInsidePosition(Mob source, Interactable target)
static int getDistance(Position source, int sourceWidth, int sourceLength, Position target, int targetWidth, int targetLength)
static Position getDelta(Position source, int sourceWidth, int sourceLength, Position target, int targetWidth, int targetLength)
static boolean withinDistance(Interactable source, Interactable target, int radius)
static Position[] getBoundaries(Interactable interactable)
static final char[] VALID_CHARS
Array of all valid characters.
static String rank(final String string)
Formats the player name.
static boolean isRegionChange(Position position, Position region)
static boolean withinOctal(Position source, int sourceWidth, int sourceLength, Position target, int targetWidth, int targetLength, int distance)
static int random(int lowerBound, int upperBound)
static boolean withinDistance(Interactable source, Position target, int radius)
static Position[] getInnerBoundaries(Position position, int width, int length)
static String getAOrAn(String nextWord)
A or an.
static boolean withinViewingDistance(Interactable source, Interactable target, int radius)
static int random(int lowerBound, int upperBound, boolean inclusive)
static String getTime()
Gets the current server time and formats it.
static Position[] getInnerBoundaries(Interactable interactable)
static boolean isLarger(Interactable source, Interactable other)
static String formatPrice(final long amount)
Formats a price for longs.
static boolean checkRequirements(Player player, int[] requirements, String action)
static boolean within(Interactable source, Interactable target, int distance)
static String getUptime()
Gets the current uptime of server and formats it.
static int min(int... values)
static< T > T randomElement(List< T > list)
Picks a random element out of any list type.
static String convertWord(int amount)
Converts an integer into words.
static int getCurrentDay()
static Position getDelta(Position source, Position target)
static final Random RANDOM
Random instance, used to generate pseudo-random primitive types.
static boolean inside(Interactable source, Position target)
static int[] shuffleArray(int[] array)
static String formatEnum(final String string)
Formats name of enum.
static long stringToLong(String string)
static boolean withinOctal(Interactable source, Interactable target, int distance)
static boolean within(Position source, Position target, int distance)
static String getSimpleDate()
Gets the date of server.
This class specially written to convert the given number into words.
String getNumberInWords()
static Words getInstance(long num)
Represents the enumerated directions an entity can walk or face.
static Direction getDirection(int deltaX, int deltaY)
Gets the direction between two locations.
Position getFaceLocation()
An object implementing Interactable has uses.
static Interactable create(Position position)
Creates a new instance of an Interactable.