FastMOTD icon indicating copy to clipboard operation
FastMOTD copied to clipboard

Can't change players count via other plugin. Maybe API? + You have small bottleneck

Open ChefMC opened this issue 7 months ago • 2 comments

Described the problem here:

https://github.com/PaperMC/Velocity/issues/1624

Maybe, if it can't be fixed, you'll add API to say FastMOTD take value which was set via FastMOTD API?


Also, btw, you have some small bottleneck:

Image

Don't do any math operations if value is constant. Do it only for dynamic values. You have + * + / on each ping, it's strongly bad ☠️

Also update your benchmarks after fixing this one ^ And find similar redundant excessive calculations

ChefMC avatar Aug 06 '25 12:08 ChefMC

I was forgot for API way, so added Redis support directly 🫣 (into FastMOTD).

Settings.java

// After `FAKE_ONLINE_ADD_PERCENT` I added this:
public String X_REDIS_URL = "";

FastMOTD.java

  // Added this:

  private boolean xIsRedis = false;
  private String xRedisUrl = null;
  private int xOnline = 111;
  private JedisPool redis = null;
  private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

  private void connectRedis() {
    if (this.redis != null) {
      try {
        this.redis.close();
      } catch (Exception ignored) {}
    }

    JedisPoolConfig poolConfig = new JedisPoolConfig();
    poolConfig.setTestOnBorrow(true);

    this.redis = new JedisPool(this.xRedisUrl);
  }

  private boolean isRedisAlive() {
    try (Jedis jedis = this.redis.getResource()) {
      jedis.ping();
      return true;
    } catch (Exception e1) {
      try {
        this.connectRedis();
        try (Jedis jedis = this.redis.getResource()) {
          jedis.ping();
          return true;
        }
      } catch (Exception e2) {
        this.xOnline = 111;
        e1.printStackTrace();
        e2.printStackTrace();
      }
    }
    return false;
  }

  private void stopRedis() {
    this.scheduler.shutdownNow();
    if (this.redis != null) {
      this.logger.info("Disconnecting from Redis...");
      this.redis.close();
      this.logger.info("Disconnected from Redis!");
    }
  }

  @Subscribe
  public void onProxyShutdown(ProxyShutdownEvent event) {
    this.stopRedis();
  }

+

  // After this:
  public void reload() {
    Settings.IMP.reload(this.configPath);

  // Added this:
    try {
      String redisUrl = Settings.IMP.MAIN.X_REDIS_URL;
      if (redisUrl != null && !redisUrl.isEmpty()) {
        this.xRedisUrl = redisUrl;
        if (!this.xIsRedis) {
          this.logger.info("Connecting to Redis...");
          this.connectRedis();
          if (this.isRedisAlive()) {
            this.logger.info("Connected to Redis!");
          } else {
            this.logger.error("Failed connect to Redis!");
          }
          this.scheduler.scheduleAtFixedRate(() -> {
            //if (!this.isRedisAlive()) {
            //  this.xOnline = 112;
            //}
            try (Jedis jedis = this.redis.getResource()) {
              Set<String> keys = jedis.keys("pl_online:*");
              int total = 0;
              for (String key : keys) {
                String value = jedis.get(key);
                if (value != null) {
                  try {
                    total += Integer.parseInt(value);
                  } catch (NumberFormatException ignored) {}
                }
              }
              this.xOnline = total;
            } catch (Exception e) {
              this.xOnline = 112;
              e.printStackTrace();
            }
          }, 0, 5, TimeUnit.SECONDS);
        }
        this.xIsRedis = true;
      } else {
        this.xRedisUrl = null;
        this.xIsRedis = false;
        this.stopRedis();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }

    // ...

+

  // Updated method:

  private int getOnline() {
    if (this.xIsRedis) {
      return this.xOnline;
    }
    int online = this.server.getPlayerCount() + Settings.IMP.MAIN.FAKE_ONLINE_ADD_SINGLE;
    if (Settings.IMP.MAIN.FAKE_ONLINE_ADD_PERCENT == 0) {
      return online;
    }
    return online * (Settings.IMP.MAIN.FAKE_ONLINE_ADD_PERCENT + 100) / 100;
  }

Btw, why do you require to use this. in checkstyle?

ChefMC avatar Aug 06 '25 20:08 ChefMC

My plugin which filling Redis with online values from backend servers: https://github.com/ChefMC/SecureTransfer

And code in comment above is retrieving them from Redis to FastMOTD

ChefMC avatar Aug 06 '25 20:08 ChefMC