From 43775016ba29b65bf7aa19e6f7d9f40f2fc130f1 Mon Sep 17 00:00:00 2001
From: ipkpjersi <33754783+ipkpjersi@users.noreply.github.com>
Date: Fri, 20 Sep 2024 23:22:26 -0400
Subject: [PATCH] Added uptime command and utility functions (#648)
* Added uptime command and utility functions
* Don't use NumberFormat it's slower
---
.../src/main/java/com/rs2/GameEngine.java | 6 +
.../com/rs2/net/packets/impl/Commands.java | 3 +
.../src/main/java/com/rs2/util/Misc.java | 743 +++++++++++++++++-
3 files changed, 747 insertions(+), 5 deletions(-)
diff --git a/2006Scape Server/src/main/java/com/rs2/GameEngine.java b/2006Scape Server/src/main/java/com/rs2/GameEngine.java
index e1495809..761015d5 100644
--- a/2006Scape Server/src/main/java/com/rs2/GameEngine.java
+++ b/2006Scape Server/src/main/java/com/rs2/GameEngine.java
@@ -116,6 +116,7 @@ public class GameEngine {
private final static ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
private final static Lock lock = new ReentrantLock();
public static ControlPanel panel;
+ private static long serverStartTime;
static {
shutdownServer = false;
@@ -123,6 +124,7 @@ public class GameEngine {
public static void main(java.lang.String[] args)
throws NullPointerException, IOException {
+ serverStartTime = System.currentTimeMillis();
if (NetworkConstants.RSA_EXPONENT != Constants.RSA_EXPONENT) {
NetworkConstants.RSA_EXPONENT = Constants.RSA_EXPONENT;
NetworkConstants.RSA_MODULUS = Constants.RSA_MODULUS;
@@ -316,4 +318,8 @@ public class GameEngine {
public static boolean playerExecuted = false;
private static BufferedReader minuteFile;
+
+ public static long getServerStartTime() {
+ return serverStartTime;
+ }
}
\ No newline at end of file
diff --git a/2006Scape Server/src/main/java/com/rs2/net/packets/impl/Commands.java b/2006Scape Server/src/main/java/com/rs2/net/packets/impl/Commands.java
index 820d71e0..6b761793 100644
--- a/2006Scape Server/src/main/java/com/rs2/net/packets/impl/Commands.java
+++ b/2006Scape Server/src/main/java/com/rs2/net/packets/impl/Commands.java
@@ -417,6 +417,9 @@ public class Commands implements PacketType {
else
player.gfx0(Integer.parseInt(arguments[0]));
break;
+ case "uptime":
+ player.getPacketSender().sendMessage("The server has now been online for: " + Misc.getServerUptime(GameEngine.getServerStartTime()));
+ break;
case "tele":
if (player.connectedFrom.equals("127.0.0.1")) {
try {
diff --git a/2006Scape Server/src/main/java/com/rs2/util/Misc.java b/2006Scape Server/src/main/java/com/rs2/util/Misc.java
index 4ec2e61a..70786754 100644
--- a/2006Scape Server/src/main/java/com/rs2/util/Misc.java
+++ b/2006Scape Server/src/main/java/com/rs2/util/Misc.java
@@ -1,7 +1,16 @@
package com.rs2.util;
-import java.text.NumberFormat;
-import java.util.ArrayList;
+import com.google.gson.Gson;
+import com.rs2.game.players.Player;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.text.*;
+import java.time.ZonedDateTime;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
public class Misc {
@@ -76,9 +85,194 @@ public class Misc {
return new String(ac, 12 - i, i);
}
- public static String format(int num) {
- return NumberFormat.getInstance().format(num);
- }
+ /**
+ * Formats digits for integers.
+ *
+ * @param amount
+ * @return
+ */
+ public static String format(final int num) {
+ String string = Integer.toString(num);
+ return string;
+ }
+
+ /**
+ * Formats a number into a string with commas.
+ */
+ public static String formatValue(int value) {
+ return new DecimalFormat("#, ###").format(value);
+ }
+
+ /** Formats digits for longs. */
+ public static String format(final long num) {
+ String string = Long.toString(num);
+ return string;
+ }
+
+ /** Formats a price for longs.
+ * @param amount*/
+ public static String formatPrice(final int amount) {
+ if (amount >= 0 && amount < 1_000) {
+ return "" + amount;
+ }
+ if (amount >= 1_000 && amount < 1_000_000) {
+ return (amount / 1_000) + "K";
+ }
+ if (amount >= 1_000_000 && amount < 1_000_000_000) {
+ return (amount / 1_000_000) + "M";
+ }
+ if (amount >= 1_000_000_000 && amount < Integer.MAX_VALUE) {
+ return (amount / 1_000_000_000) + "B";
+ }
+ return "
Lots!";
+ }
+
+ /**
+ * @return 5.5 for example.
+ */
+ public static double roundDoubleToNearestOneDecimalPlace(double number) {
+ DecimalFormat df = new DecimalFormat("#.#");
+ return Double.parseDouble(df.format(number));
+ }
+
+ /**
+ * Shorted to 5.66 for example.
+ */
+ public static double roundDoubleToNearestTwoDecimalPlaces(double number) {
+ DecimalFormat df = new DecimalFormat("#.##");
+ return Double.parseDouble(df.format(number));
+ }
+
+ public static double getDoubleRoundedUp(double doubleNumber) {
+ return Math.ceil(doubleNumber);
+ }
+
+ public static double getDoubleRoundedDown(double doubleNumber) {
+ return (double) ((int) doubleNumber);
+ }
+
+ public static String formatRunescapeStyle(long num) {
+ boolean negative = false;
+ if (num < 0) {
+ num = -num;
+ negative = true;
+ }
+ int length = String.valueOf(num).length();
+ String number = Long.toString(num);
+ String numberString = number;
+ String end = "";
+ if (length == 4) {
+ numberString = number.substring(0, 1) + "k";
+ //6400
+ double doubleVersion = 0.0;
+ doubleVersion = num / 1000.0;
+ if (doubleVersion != getDoubleRoundedUp(doubleVersion)) {
+ if (num - (1000 * getDoubleRoundedDown(doubleVersion)) > 100) {
+ numberString = number.substring(0, 1) + "." + number.substring(1, 2) + "k";
+ }
+ }
+ } else if (length == 5) {
+ numberString = number.substring(0, 2) + "k";
+ } else if (length == 6) {
+ numberString = number.substring(0, 3) + "k";
+ } else if (length == 7) {
+ String sub = number.substring(1, 2);
+ if (sub.equals("0")) {
+ numberString = number.substring(0, 1) + "m";
+ } else {
+ numberString = number.substring(0, 1) + "." + number.substring(1, 2) + "m";
+ }
+ } else if (length == 8) {
+ end = "." + number.substring(2, 3);
+ if (end.equals(".0")) {
+ end = "";
+ }
+ numberString = number.substring(0, 2) + end + "m";
+ } else if (length == 9) {
+ end = "." + number.substring(3, 4);
+ if (end.equals(".0")) {
+ end = "";
+ }
+ numberString = number.substring(0, 3) + end + "m";
+ } else if (length == 10) {
+ numberString = number.substring(0, 4) + "m";
+ } else if (length == 11) {
+ numberString = number.substring(0, 2) + "." + number.substring(2, 5) + "b";
+ } else if (length == 12) {
+ numberString = number.substring(0, 3) + "." + number.substring(3, 6) + "b";
+ } else if (length == 13) {
+ numberString = number.substring(0, 4) + "." + number.substring(4, 7) + "b";
+ }
+ if (negative) {
+ numberString = "-" + numberString;
+ }
+ return numberString;
+ }
+
+ public static String formatText(String s) {
+ for (int i = 0; i < s.length(); i++) {
+ if (i == 0) {
+ s = String.format("%s%s", Character.toUpperCase(s.charAt(0)),
+ s.substring(1));
+ }
+ if (!Character.isLetterOrDigit(s.charAt(i))) {
+ if (i + 1 < s.length()) {
+ s = String.format("%s%s%s", s.subSequence(0, i + 1),
+ Character.toUpperCase(s.charAt(i + 1)),
+ s.substring(i + 2));
+ }
+ }
+ }
+ return s.replace("_", " ");
+ }
+
+ public static String formatTextUnderscore(String s) {
+ for (int i = 0; i < s.length(); i++) {
+ if (i == 0) {
+ s = String.format("%s%s", Character.toUpperCase(s.charAt(0)),
+ s.substring(1));
+ }
+ if (!Character.isLetterOrDigit(s.charAt(i))) {
+ if (i + 1 < s.length()) {
+ s = String.format("%s%s%s", s.subSequence(0, i + 1),
+ Character.toUpperCase(s.charAt(i + 1)),
+ s.substring(i + 2));
+ }
+ }
+ }
+ return s.replace(" ", "_");
+ }
+
+ public static String optimizeTextNew(String text) {
+ for (int index = 0; index < text.length(); index++) {
+ if (index == 0) {
+ text = String.format("%s%s", Character.toUpperCase(text.charAt(0)), text.substring(1));
+ }
+ if (!Character.isLetterOrDigit(text.charAt(index))) {
+ if (index + 1 < text.length()) {
+ text = String.format("%s%s%s", text.subSequence(0, index + 1), Character.toUpperCase(text.charAt(index + 1)), text.substring(index + 2));
+ }
+ }
+ }
+ return text;
+ }
+
+ public static String getTotalAmount(int j) {
+ if (j >= 10000 && j < 1000000) {
+ return j / 1000 + "K";
+ } else if (j >= 1000000 && j <= Integer.MAX_VALUE) {
+ return j / 1000000 + "M";
+ } else {
+ return "" + j;
+ }
+ }
+
+ public static String insertCommasToNumber(String number) {
+ return number.length() < 4 ? number : insertCommasToNumber(number
+ .substring(0, number.length() - 3))
+ + ","
+ + number.substring(number.length() - 3, number.length());
+ }
public static String ucFirst(String str) {
str = str.toLowerCase();
@@ -89,6 +283,41 @@ public class Misc {
}
return str;
}
+
+ /**
+ * Format number into for example: 357,555
+ */
+ public static String formatNumber(long number) {
+ // Do not use return NumberFormat.getIntegerInstance().format(number);. It is 9 times slower.
+ String string = Long.toString(number);
+ if (number < 1000) {
+ return string;
+ }
+ if (number >= 1000 && number < 10000) {
+ return string.substring(0, 1) + "," + string.substring(1);
+ }
+ if (number < 100000) {
+ return string.substring(0, 2) + "," + string.substring(2);
+ }
+ if (number < 1000000) {
+ return string.substring(0, 3) + "," + string.substring(3);
+ }
+ if (number < 10000000) {
+ return string.substring(0, 1) + "," + string.substring(1, 4) + "," + string.substring(4, 7);
+ }
+ if (number < 100000000) {
+ return string.substring(0, 2) + "," + string.substring(2, 5) + "," + string.substring(5, 8);
+ }
+ if (number < 1000000000) {
+ return string.substring(0, 3) + "," + string.substring(3, 6) + "," + string.substring(6, 9);
+ }
+ if (number <= Integer.MAX_VALUE) {
+ return string.substring(0, 1) + "," + string.substring(1, 4) + "," + string.substring(4, 7) + "," + string.substring(7, 10);
+ }
+ return string;
+ }
+
+
public static String Hex(byte data[]) {
return Hex(data, 0, data.length);
@@ -287,4 +516,508 @@ public class Misc {
}
return s;
}
+
+ public static int toCyclesOrDefault(long time, int def, TimeUnit unit) {
+ if (time > Integer.MAX_VALUE) {
+ time = def;
+ }
+ return (int) TimeUnit.MILLISECONDS.convert(time, unit) / 600;
+ }
+
+ public static > List> sortEntries(Map map) {
+ List> sortedEntries = new ArrayList>(map.entrySet());
+ Collections.sort(sortedEntries, (e1, e2) -> e2.getValue().compareTo(e1.getValue()));
+ return sortedEntries;
+ }
+
+ public static Map sortByComparator(Map unsortMap, final boolean ascending)
+ {
+ List> list = new LinkedList>(unsortMap.entrySet());
+ // Sorting the list based on values
+ list.sort(new Comparator>() {
+ public int compare(Map.Entry o1,
+ Map.Entry o2) {
+ if (ascending) {
+ return o1.getValue().compareTo(o2.getValue());
+ } else {
+ return o2.getValue().compareTo(o1.getValue());
+ }
+ }
+ });
+ // Maintaining insertion order with the help of LinkedList
+ Map sortedMap = new LinkedHashMap();
+ for (Map.Entry entry : list)
+ {
+ sortedMap.put(entry.getKey(), entry.getValue());
+ }
+ return sortedMap;
+ }
+
+ public static List jsonArrayToList(Path path, Class clazz) {
+ try {
+ T[] collection = new Gson().fromJson(Files.newBufferedReader(path), clazz);
+ return new ArrayList(Arrays.asList(collection));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public static String kOrMil(int amount) {
+ if (amount < 100_000)
+ return String.valueOf(amount);
+ if (amount < 10_000_000)
+ return amount / 1_000 + "K";
+ else
+ return amount / 1_000_000 + "M";
+ }
+
+ public static int[] convertRollRangeStringToIntArray(String input)
+ {
+ String[] strArray = input.split("-");
+ int[] intArray = new int[strArray.length];
+ for (int i = 0; i < strArray.length; i++) {
+ intArray[i] = Integer.parseInt(strArray[i]);
+ }
+ return intArray;
+ }
+
+ /**
+ * Random instance, used to generate pseudo-random primitive types.
+ */
+ public static final Random RANDOM = new Random();
+
+ /**
+ * Finds out if a certain event should happen, and if it should, return
+ * true;
+ *
+ * @param chance
+ * The chance of the event happening
+ * @return If the event should happen
+ */
+ public static boolean percentageChance(int chance) {
+ return RANDOM.nextInt(100) < chance;
+ }
+
+ public static String getFractionFromPercentage(float percentage) {
+ return "1 / " + (int) Math.round((1 / percentage) * 100); //Was ceil is now round
+ }
+
+ public static int getDenominatorFromPercentage(float percentage) {
+ return (int) Math.round((1 / percentage) * 100); //Was ceil is now round
+ }
+
+ public static String getCurrentServerTime() {
+ ZonedDateTime zonedDateTime = ZonedDateTime.now();
+ int hour = zonedDateTime.getHour();
+ String hourPrefix = hour < 10 ? "0" + hour + "" : "" + hour + "";
+ int minute = zonedDateTime.getMinute();
+ String minutePrefix = minute < 10 ? "0" + minute + "" : "" + minute + "";
+ return "" + hourPrefix + ":" + minutePrefix + "";
+ }
+ public static String getCurrentServerDateTime() {
+ DateFormat dateFormat = new SimpleDateFormat("dd MMM yyyy, h:mm:ss a");
+ Calendar calendar = Calendar.getInstance();
+ return dateFormat.format(calendar.getTime());
+ }
+
+ /**
+ * Gets the formatted time played.
+ *
+ * @return The time played formatted as a string.
+ */
+ public static String getFormattedPlayTime(Player player, long creationTime) {
+ long different = System.currentTimeMillis() - creationTime;
+
+
+ long secondsInMilli = 1000;
+ long minutesInMilli = secondsInMilli * 60;
+ long hoursInMilli = minutesInMilli * 60;
+ long daysInMilli = hoursInMilli * 24;
+
+ long elapsedDays = different / daysInMilli;
+ different = different % daysInMilli;
+
+ long elapsedHours = different / hoursInMilli;
+ different = different % hoursInMilli;
+
+ long elapsedMinutes = different / minutesInMilli;
+ different = different % minutesInMilli;
+
+ long elapsedSeconds = different / secondsInMilli;
+
+ /* long days = (long) elapsedJoinDate / 86400; // 86,400
+ long daysRemainder = (long) elapsedJoinDate - (days * 86400);
+ long hours = (long) daysRemainder / 3600; // 3,600
+ long hoursRemainder = (long) daysRemainder - (hours * 3600);
+ long minutes = (long) hoursRemainder / 60; // 60
+ long seconds = (long) hoursRemainder - (minutes * 60); // remainder*/
+
+ return elapsedDays + "d " + elapsedHours + "h " + elapsedMinutes + "m " + elapsedSeconds + "s";
+
+ }
+
+ public static String getTimePlayed(long totalPlayTime) {
+ final int sec = (int) (totalPlayTime / 1000), h = sec / 3600, m = sec / 60 % 60, s = sec % 60;
+ return (h < 10 ? "0" + h : h) + ":" + (m < 10 ? "0" + m : m) + ":" + (s < 10 ? "0" + s : s);
+ }
+
+ public static String getHoursPlayed(long totalPlayTime) {
+ final int sec = (int) (totalPlayTime / 1000), h = sec / 3600;
+ return (h < 10 ? "0" + h : h) + "h";
+ }
+
+ public static String asMinutesLeft(int ticksLeft) {
+ long ms = ticksLeft * 600;
+ int minutes = (int) TimeUnit.MILLISECONDS.toMinutes(ms);
+ String str = "";
+
+ if (minutes > 0) {
+ if (minutes > 1) {
+ str = minutes + " mins";
+ } else {
+ str = "One min";
+ }
+ }
+
+ return str;
+ }
+
+ public static String asSeconds(int ticksLeft) {
+ long ms = ticksLeft * 600;
+ int seconds = (int) TimeUnit.MILLISECONDS.toSeconds(ms);
+ String str = "";
+
+
+ if (seconds > 1) {
+ str = seconds + " seconds";
+ } else {
+ str = "One second";
+ }
+
+ return str;
+ }
+
+ public static int getMinutesPassed(long t) {
+ int seconds = (int) ((t / 1000) % 60);
+ int minutes = (int) (((t - seconds) / 1000) / 60);
+ return minutes;
+ }
+
+ /**
+ * Useful method for getting the stack trace where some code
+ * was executed without throwing an exception.
+ * This method basically makes it so that we don't have to throw new RuntimeException
+ * in order to get a stack trace.
+ * @return the stack trace
+ */
+ public static String getStackTrace() {
+ final StringWriter writer = new StringWriter();
+ new Exception("Stack trace").printStackTrace(new PrintWriter(writer));
+ return writer.toString();
+ }
+
+ public static float getPercentageFromDecimal(float decimal) {
+ return decimal * 100;
+ }
+
+ public static float getPercentageFromDenominator(float denominator) {
+ return (1 / denominator) * 100;
+ }
+
+ public static float getDecimalFromFraction(int numerator, int denominator) {
+ return (float) numerator / denominator;
+ }
+
+ public static float getDecimalFromDenominator(int denominator) {
+ return (float) 1 / denominator;
+ }
+
+ /** Gets the date of server. */
+ public static String getDate() {
+ return new SimpleDateFormat("EE MMM dd yyyy").format(new Date());
+ }
+
+ /** Gets the date of server. */
+ public static String getSimpleDate() {
+ return new SimpleDateFormat("yyyy/MM/dd").format(new Date());
+ }
+
+ public static String pluralOrNot(String word, int count) {
+ String value = "";
+ if (count == 0 || count > 1) {
+ value = word + "s";
+ } else {
+ value = word;
+ }
+ return value;
+ }
+
+ public static float ticksToSeconds(int tick) {
+ int ticksInMillis = tick * 600;
+ float tickToSecs = ticksInMillis / 1000f;
+ return tickToSecs;
+ }
+
+ public static float ticksToMinutes(int tick) {
+ int ticksInMillis = tick * 600;
+ float tickToMin = ticksInMillis / 60000f;
+ return tickToMin;
+ }
+
+ public static float ticksToHours(int tick) {
+ int ticksInMillis = tick * 600;
+ float tickToHour = ticksInMillis / 3_600_000f;
+ return tickToHour;
+ }
+
+ public static String convertLongToDateTime(long time) {
+ Date date = new Date(time);
+ //Format format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+ Format format = new SimpleDateFormat("dd MMM yyyy h:mm:ss a");
+ return format.format(date);
+ }
+
+ public static String convertLongToTime(long time) {
+ Date date = new Date(time);
+ Format format = new SimpleDateFormat("h:mm:ss a");
+ return format.format(date);
+ }
+
+ public static String convertLongToDate(long time) {
+ Date date = new Date(time);
+ //Format format = new SimpleDateFormat("yyyy-MM-dd");
+ Format format = new SimpleDateFormat("dd MMM yyyy");
+ return format.format(date);
+ }
+
+ public static String convertLongToDuration(long time) {
+ if (time < 0) {
+ throw new IllegalArgumentException("Duration must be greater than zero!");
+ }
+
+ long days = TimeUnit.MILLISECONDS.toDays(time);
+ time -= TimeUnit.DAYS.toMillis(days);
+ long hours = TimeUnit.MILLISECONDS.toHours(time);
+ time -= TimeUnit.HOURS.toMillis(hours);
+ long minutes = TimeUnit.MILLISECONDS.toMinutes(time);
+ time -= TimeUnit.MINUTES.toMillis(minutes);
+ long seconds = TimeUnit.MILLISECONDS.toSeconds(time);
+
+ StringBuilder sb = new StringBuilder(64);
+ sb.append(days);
+ sb.append((days > 1 || days == 0) ? " days " : " day ");
+ sb.append(hours);
+ sb.append((hours > 1 || hours == 0) ? " hours " : " hour ");
+ sb.append(minutes);
+ sb.append((minutes > 1 || minutes == 0) ? " minutes " : " minute ");
+ sb.append(seconds);
+ sb.append((seconds > 1 || seconds == 0) ? " seconds" : " second");
+
+ return (sb.toString());
+ }
+
+ public static String convertLongToShortDuration(long time, boolean useSeconds) {
+ if (time < 0) {
+ throw new IllegalArgumentException("Duration must be greater than zero!");
+ }
+ long days = TimeUnit.MILLISECONDS.toDays(time);
+ time -= TimeUnit.DAYS.toMillis(days);
+ long hours = TimeUnit.MILLISECONDS.toHours(time);
+ time -= TimeUnit.HOURS.toMillis(hours);
+ long minutes = TimeUnit.MILLISECONDS.toMinutes(time);
+ time -= TimeUnit.MINUTES.toMillis(minutes);
+ long seconds = TimeUnit.MILLISECONDS.toSeconds(time);
+
+
+ StringBuilder sb = new StringBuilder(64);
+ sb.append(days);
+ sb.append("d ");
+ sb.append(hours);
+ sb.append("h ");
+ sb.append(minutes);
+ sb.append("m ");
+ if (useSeconds) {
+ sb.append(seconds);
+ sb.append("s ");
+ }
+
+
+ return (sb.toString());
+ }
+
+ public static String convertSecondsToShortDuration(long time, boolean useSeconds) {
+ if (time < 0) {
+ throw new IllegalArgumentException("Duration must be greater than zero!");
+ }
+
+ long days = (int)TimeUnit.SECONDS.toDays(time);
+ long hours = TimeUnit.SECONDS.toHours(time) - (days *24);
+ long minutes = TimeUnit.SECONDS.toMinutes(time) - (TimeUnit.SECONDS.toHours(time)* 60);
+ long seconds = TimeUnit.SECONDS.toSeconds(time) - (TimeUnit.SECONDS.toMinutes(time) *60);
+
+
+ StringBuilder sb = new StringBuilder(64);
+ sb.append(days);
+ sb.append("d ");
+ sb.append(hours);
+ sb.append("h ");
+ sb.append(minutes);
+ sb.append("m ");
+ if (useSeconds) {
+ sb.append(seconds);
+ sb.append("s ");
+ }
+
+ return (sb.toString());
+ }
+
+ public static String convertSecondsToDuration(long time, boolean showDaysAndHours) {
+ if (time < 0) {
+ throw new IllegalArgumentException("Duration must be greater than zero!");
+ }
+
+ long days = (int)TimeUnit.SECONDS.toDays(time);
+ long hours = TimeUnit.SECONDS.toHours(time) - (days *24);
+ long minutes = TimeUnit.SECONDS.toMinutes(time) - (TimeUnit.SECONDS.toHours(time)* 60);
+ long seconds = TimeUnit.SECONDS.toSeconds(time) - (TimeUnit.SECONDS.toMinutes(time) *60);
+
+ StringBuilder sb = new StringBuilder(64);
+ if (showDaysAndHours) {
+ sb.append(days);
+ sb.append((days > 1 || days == 0) ? " days " : " day ");
+ sb.append(hours);
+ sb.append((hours > 1 || hours == 0) ? " hours " : " hour ");
+ sb.append(minutes);
+ sb.append((minutes > 1 || minutes == 0) ? " minutes " : " minute ");
+ sb.append(seconds);
+ sb.append((seconds > 1 || seconds == 0) ? " seconds" : " second");
+ } else {
+ sb.append(minutes);
+ sb.append((minutes > 1 || minutes == 0) ? " minutes " : " minute ");
+ sb.append(seconds);
+ sb.append((seconds > 1 || seconds == 0) ? " seconds" : " second");
+ }
+
+ return (sb.toString());
+ }
+
+ public static int getMinutesElapsed(int minute, int hour, int day, int year) {
+ Calendar i = Calendar.getInstance();
+
+ if (i.get(1) == year) {
+ if (i.get(6) == day) {
+ if (hour == i.get(11)) {
+ return i.get(12) - minute;
+ }
+ return (i.get(11) - hour) * 60 + (59 - i.get(12));
+ }
+
+ int ela = (i.get(6) - day) * 24 * 60 * 60;
+ return ela > 2147483647 ? 2147483647 : ela;
+ }
+
+ int ela = getElapsed(day, year) * 24 * 60 * 60;
+
+ return ela > 2147483647 ? 2147483647 : ela;
+ }
+
+ public static int getDayOfYear() {
+ Calendar c = Calendar.getInstance();
+ int year = c.get(Calendar.YEAR);
+ int month = c.get(Calendar.MONTH);
+ int days = 0;
+ int[] daysOfTheMonth = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+ if ((year % 4 == 0) && (year % 100 != 0) || (year % 400 == 0)) {
+ daysOfTheMonth[1] = 29;
+ }
+ days += c.get(Calendar.DAY_OF_MONTH);
+ for (int i = 0; i < daysOfTheMonth.length; i++) {
+ if (i < month) {
+ days += daysOfTheMonth[i];
+ }
+ }
+ return days;
+ }
+
+ public static int getYear() {
+ Calendar c = Calendar.getInstance();
+ return c.get(Calendar.YEAR);
+ }
+
+ public static int getElapsed(int day, int year) {
+ if (year < 2013) {
+ return 0;
+ }
+
+ int elapsed = 0;
+ int currentYear = Misc.getYear();
+ int currentDay = Misc.getDayOfYear();
+
+ if (currentYear == year) {
+ elapsed = currentDay - day;
+ } else {
+ elapsed = currentDay;
+
+ for (int i = 1; i < 5; i++) {
+ if (currentYear - i == year) {
+ elapsed += 365 - day;
+ break;
+ } else {
+ elapsed += 365;
+ }
+ }
+ }
+
+ return elapsed;
+ }
+
+ public static boolean isWeekend() {
+ int day = Calendar.getInstance().get(7);
+ return (day == 1) || (day == 6) || (day == 7);
+ }
+
+ public static int getTicks(int seconds) {
+ return (int) (seconds / 0.6);
+ }
+
+ public static int getSeconds(int ticks) {
+ return (int) (ticks * 0.6);
+ }
+ public static String getServerUptime(long serverStartTime) {
+ long currentTime = System.currentTimeMillis();
+ long uptimeMillis = currentTime - serverStartTime;
+
+ long seconds = (uptimeMillis / 1000) % 60;
+ long minutes = (uptimeMillis / (1000 * 60)) % 60;
+ long hours = (uptimeMillis / (1000 * 60 * 60)) % 24;
+ long days = uptimeMillis / (1000 * 60 * 60 * 24);
+
+ return String.format("%d days, %d hours, %d minutes, %d seconds", days, hours, minutes, seconds);
+ }
+
+ public static double roundOneDecimal(double number_to_format) {
+ DecimalFormat decimal_format = new DecimalFormat("#.#");
+ return Double.parseDouble(decimal_format.format(number_to_format).replace(",", "."));
+ }
+
+ public static double round(double number_to_format) {
+ DecimalFormat decimal_format = new DecimalFormat("#.##");
+ return Double.parseDouble(decimal_format.format(number_to_format).replace(",", "."));
+ }
+
+ public static boolean rollDie(int dieSides, int chance) {
+ return random(dieSides) < chance;
+ }
+
+ public static String capitalizeJustFirst(String str) {
+ str = str.toLowerCase();
+ if (str.length() > 1) {
+ str = str.substring(0, 1).toUpperCase() + str.substring(1);
+ } else {
+ return str.toUpperCase();
+ }
+ return str;
+ }
+
}