Skip to content

Commit

Permalink
Move most lagstat strings to messages.properties. (#154)
Browse files Browse the repository at this point in the history
  • Loading branch information
hopskipnfall authored Feb 5, 2025
1 parent ef142a6 commit 1587720
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 29 deletions.
14 changes: 14 additions & 0 deletions emulinker/src/main/i18n/messages.properties
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,17 @@ GameOwnerCommandAction.AutoFireChangeDeniedInGame=All players must drop the game
KailleraServerImpl.TweetPendingAnnouncement=Posting a tweet in {0,number,integer} seconds. Type \"/stop\" to disable.
KailleraServerImpl.TweetCloseMessage=(opponent found)
KailleraServerImpl.CanceledPendingTweet=Canceled pending tweet.

Lagstat.GameNotLaggy=The game does not appear to be significantly laggy.
Lagstat.LagstatReset=LagStat has been reset!
! Error message displayed if you run /lagstat too early after the game starts.
Lagstat.LagstatNotReady=Wait a minute or so after the game starts to run lagstat.
! Example: Total lag over the last 1.0m: 0.02s
Lagstat.TotalGameLagSummary=Total lag over the last {}: {}
! Example: Recommendation: nue should try playing on 2f. Enter 25 in the ping spoof field when joining. If lag continues, run /lagstat again.
Lagstat.LagReductionRecommendation=Recommendation: {} should try playing on {number,integer}f. Enter {number,integer} in the ping spoof field when joining. If lag continues, run /lagstat again.

! Measurement of seconds. Examples: 0.03s, 1s
Time.SecondsAbbreviation={number}s
! Measurement of minutes. Examples: 0.5m, 1m
Time.MinutesAbbreviation={number}m
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ import org.emulinker.kaillera.model.event.GameChatEvent
import org.emulinker.kaillera.model.exception.ActionException
import org.emulinker.kaillera.model.exception.GameChatException
import org.emulinker.kaillera.model.impl.KailleraGameImpl
import org.emulinker.util.EmuLang
import org.emulinker.util.EmuLang.getStringOrNull
import org.emulinker.util.EmuUtil.min
import org.emulinker.util.EmuUtil.threadSleep
import org.emulinker.util.EmuUtil.toLocalizedString
import org.emulinker.util.EmuUtil.toMillisDouble
import org.emulinker.util.EmuUtil.toSecondDoublePrecisionString

Expand Down Expand Up @@ -464,23 +466,26 @@ class GameChatAction(
game.chat(clientHandler.user, message.message)
// Note: This was duplicated from GameOwnerCommandAction.
if (!game.startTimeout) {
game.announce("Wait a minute or so after the game starts to run lagstat.")
game.announce(EmuLang.getString("Lagstat.LagstatNotReady"))
return
}
val lagstatDuration = min(flags.lagstatDuration, clock.now() - game.lastLagReset)
val lagstatDurationAsString =
if (lagstatDuration < 1.minutes) {
lagstatDuration.toString(SECONDS)
lagstatDuration.toLocalizedString(SECONDS)
} else {
lagstatDuration.toString(MINUTES, 1)
lagstatDuration.toLocalizedString(MINUTES, 1)
}
val gameLag =
(game.totalDriftNs - (game.totalDriftCache.getDelayedValue() ?: 0))
.nanoseconds
.absoluteValue
game.announce(
"Total lag over the last ${lagstatDurationAsString}: " +
gameLag.toSecondDoublePrecisionString()
EmuLang.getString(
"Lagstat.TotalGameLagSummary",
lagstatDurationAsString,
gameLag.toSecondDoublePrecisionString(),
)
)
game.announce(
"Lag definitively caused by players: " +
Expand Down Expand Up @@ -516,11 +521,16 @@ class GameChatAction(
.milliseconds

game.announce(
"Recommendation: ${laggiestPlayer.name} should try playing on $targetFrameDelay frames. Enter ${suggestedFakePing.toMillisDouble().roundToInt()} in the ping spoof field when joining. If lag continues, run /lagstat again."
EmuLang.getString(
"Lagstat.LagReductionRecommendation",
laggiestPlayer.name,
targetFrameDelay,
suggestedFakePing.toMillisDouble().roundToInt(),
)
)
}
} else {
game.announce("The game does not appear to be significantly laggy.")
game.announce(EmuLang.getString("Lagstat.GameNotLaggy"))
}
}
} else if (message.message == "/lagreset") {
Expand All @@ -529,7 +539,7 @@ class GameChatAction(
player.resetLag()
}
game.resetLag()
game.announce("LagStat has been reset!")
game.announce("Lagstat.LagstatReset")
} else if (
message.message.startsWith("/fps ") &&
message.message.removePrefix("/fps ").toDoubleOrNull() != null &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ package org.emulinker.util

import java.lang.Exception
import java.text.MessageFormat
import java.util.Locale
import java.util.ResourceBundle

object CustomUserStrings {
private const val BUNDLE_NAME = "language"

private val RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME, Locale.ENGLISH)
private val RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME)

/*
public static void reload()
Expand Down
18 changes: 0 additions & 18 deletions emulinker/src/main/java/org/emulinker/util/EmuLang.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,6 @@ object EmuLang {

private val logger = FluentLogger.forEnclosingClass()

/*
public static void reload()
{
try
{
Class klass = RESOURCE_BUNDLE.getClass().getSuperclass();
Field field = klass.getDeclaredField("cacheList");
field.setAccessible(true);
sun.misc.SoftCache cache = (sun.misc.SoftCache)field.get(null);
cache.clear();
}
catch(Exception e)
{
}
}
*/

fun hasString(key: String): Boolean {
if (RESOURCE_BUNDLE.containsKey(key)) {
try {
Expand Down
25 changes: 24 additions & 1 deletion emulinker/src/main/java/org/emulinker/util/EmuUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import kotlin.system.measureNanoTime
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.minutes
import kotlin.time.DurationUnit
import kotlin.time.DurationUnit.MINUTES
import kotlin.time.DurationUnit.SECONDS
import kotlinx.datetime.Instant
Expand Down Expand Up @@ -304,6 +305,28 @@ object EmuUtil {
)
}

/**
* Similar to [Duration.toString()] except localized to the language.
*
* For example: 5s in English and 5秒 in Japanese.
*/
fun Duration.toLocalizedString(unit: DurationUnit, decimals: Int = 0): String =
when (unit) {
DurationUnit.NANOSECONDS,
DurationUnit.MICROSECONDS,
DurationUnit.MILLISECONDS,
DurationUnit.HOURS,
DurationUnit.DAYS -> TODO("Unit $unit not yet supported")
SECONDS -> {
val number = this.toString(unit, decimals).removeSuffix("s")
EmuLang.getString("Time.SecondsAbbreviation", number)
}
MINUTES -> {
val number = this.toString(unit, decimals).removeSuffix("m")
EmuLang.getString("Time.MinutesAbbreviation", number)
}
}

// TODO(nue): Get rid of this after it's confirmed it can be safely removed.
/** NOOP placeholder for a function that _used to_ call [Thread.sleep]. */
@Deprecated(
Expand All @@ -327,5 +350,5 @@ object EmuUtil {
this.inWholeNanoseconds / 1.milliseconds.inWholeNanoseconds.toDouble()

fun Duration.toSecondDoublePrecisionString() =
if (this < 1.minutes) toString(SECONDS, 2) else toString(MINUTES, 1)
if (this < 1.minutes) toLocalizedString(SECONDS, 2) else toLocalizedString(MINUTES, 1)
}

0 comments on commit 1587720

Please sign in to comment.