1
Fork 0
mirror of https://github.com/Quackster/Havana.git synced 2025-07-02 04:37:47 +00:00

feat: Poker by wackfx

This commit is contained in:
Quackster 2025-04-23 18:40:07 +10:00
parent 4eed29c0f9
commit 3395b3bcd5
9 changed files with 704 additions and 28 deletions

View file

@ -51,6 +51,7 @@ public class GameBattleShip extends GamehallGame {
this.gameEnded = false;
}
/*
@Override
public void joinGame(Player player) {
if (!this.gameStarted) {
@ -78,7 +79,8 @@ public class GameBattleShip extends GamehallGame {
this.sendToEveryone(new ITEMMSG(new String[]{this.getGameId(), "OPPONENTS", String.join(Character.toString((char) 13), opponentData)}));
this.sendMarkedMap();
}
*/
/*
@Override
public void leaveGame(Player player) {
if (this.nextTurn == getPlayerNum(player)) {
@ -92,6 +94,8 @@ public class GameBattleShip extends GamehallGame {
}
}
*/
@Override
public void handleCommand(Player player, Room room, Item item, String command, String[] args) {
GameTrigger trigger = (GameTrigger) item.getDefinition().getInteractionType().getTrigger();

View file

@ -54,14 +54,12 @@ public class GameChess extends GamehallGame {
this.board = null;
}
@Override
public void joinGame(Player player) { }
/*
@Override
public void leaveGame(Player player) {
this.playerSides.remove(player);
}
*/
@Override
public void handleCommand(Player player, Room room, Item item, String command, String[] args) {
GameTrigger trigger = (GameTrigger) item.getDefinition().getInteractionType().getTrigger();

View file

@ -1,39 +1,293 @@
package org.alexdev.havana.game.games.gamehalls;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.alexdev.havana.game.games.gamehalls.utils.GamePokerCombination;
import org.alexdev.havana.game.games.gamehalls.utils.GamePokerOptions;
import org.alexdev.havana.game.games.triggers.GameTrigger;
import org.alexdev.havana.game.item.Item;
import org.alexdev.havana.game.player.Player;
import org.alexdev.havana.game.room.Room;
import org.alexdev.havana.game.games.triggers.GameTrigger;
import java.util.List;
import org.alexdev.havana.messages.outgoing.rooms.games.ITEMMSG;
import org.alexdev.havana.messages.types.MessageComposer;
public class GamePoker extends GamehallGame {
public GamePoker(List<int[]> kvp) {
super(kvp);
}
@Override
public void gameStart() { }
// Players that played at least one round (not on open screen)
private List<Player> playersInGame;
// Players that are currently in round
private List<Player> playersPlaying;
// Changes and cards for this round
private List<String> deck;
private Map<Player, String[]> playerChanges;
private Map<Player, List<String>> playerCards;
private GamePokerOptions options;
@Override
public void gameStop() { }
public void gameStart() {
this.deck = new ArrayList<>();
this.playerCards = new HashMap<>();
this.playerChanges = new HashMap<>();
this.playersInGame = new ArrayList<>();
this.playersPlaying = new ArrayList<>();
this.options = new GamePokerOptions(this);
}
@Override
public void joinGame(Player p) { }
@Override
public void leaveGame(Player player) { }
public void gameStop() {
this.clearRound();
this.playersInGame.clear();
}
@Override
public void handleCommand(Player player, Room room, Item item, String command, String[] args) {
GameTrigger trigger = (GameTrigger) item.getDefinition().getInteractionType().getTrigger();
if (command.equals("CLOSE")) {
trigger.onEntityLeave(player, player.getRoomUser(), item);
return;
switch (command) {
case "CLOSE" -> {
trigger.onEntityLeave(player, player.getRoomUser(), item);
this.getDisconnectedPlayers().stream().forEach(this::disconnectPlayer);
if (this.isRoundRunning() && this.hasEveryoneChanged())
this.endRound();
return;
}
case "OPEN" -> {
this.getDisconnectedPlayers().stream().forEach(this::disconnectPlayer);
this.broadcastOpponents(player);
return;
}
case "STARTOVER" -> {
if (!this.isRoundRunning()) {
this.clearRound();
this.deck.addAll(GamePokerCombination.getDeck());
}
this.addPlayerToGame(player);
this.addPlayerToRound(player);
this.giveCardsToPlayer(player);
this.broadcastOpponents();
return;
}
case "CHANGE" -> {
this.getDisconnectedPlayers().stream().forEach(this::disconnectPlayer);
this.changeCards(player, args);
this.broadcastOpponents();
if (this.isRoundRunning() && this.hasEveryoneChanged())
this.endRound();
return;
}
}
}
private void addPlayerToGame(Player player) {
if (this.playersInGame.contains(player))
return;
this.playersInGame.add(player);
this.broadcastOpponents();
}
private void addPlayerToRound(Player player) {
this.playersPlaying.add(player);
// Update player with latest state
this.playerChanges.keySet().stream()
.map(key -> this.formatPlayerChangedUpdate(key))
.forEach(entry -> player.send(new ITEMMSG(entry)));
this.options.onEntry(player);
}
private void giveCardsToPlayer(Player player) {
List<String> cards = IntStream.rangeClosed(0, 4)
.mapToObj(i -> this.deck.remove(ThreadLocalRandom.current().nextInt(this.deck.size())))
.toList();
this.playerCards.put(player, cards);
this.playerChanges.remove(player);
player.send(new ITEMMSG(new String[]{this.getGameId(), "YOURCARDS 0/" + this.formatRevealCardsUpdate(player)}));
}
private void changeCards(Player player, String[] sIndexes) {
if (this.playerChanges.containsKey(player))
return;
List<String> playerHand = this.playerCards.get(player);
List<Integer> cardsToChange = Arrays.asList(sIndexes)
.stream()
.filter(predicate -> !predicate.isBlank())
.map(Integer::parseInt)
.filter(index -> index >= 0 && index < playerHand.size())
.sorted().collect(Collectors.toList());
List<String> changeHand = playerHand.stream()
.map(card -> {
int index = playerHand.indexOf(card);
if (cardsToChange.contains(index))
return this.deck.remove(ThreadLocalRandom.current().nextInt(this.deck.size()));
else
return card;
})
.collect(Collectors.toList());
String[] cardsChanged = cardsToChange.stream().map(String::valueOf).toArray(String[]::new);
this.playerCards.put(player, changeHand);
this.playerChanges.put(player, cardsChanged);
// Send change event & reveal new cards to player
this.sentToPlayingOpponents(player, new ITEMMSG(
this.formatPlayerChangedUpdate(player)
));
player.send(new ITEMMSG(
String.join(Character.toString((char) 13), new String[]{
this.getGameId(),
"YOURCARDS 0/" + this.formatRevealCardsUpdate(player)
}))
);
}
private String formatPlayerChangedUpdate(Player player) {
if (!this.playerChanges.containsKey(player))
return "";
String[] cardsChanged = this.playerChanges.get(player);
String change = player.getDetails().getName() + "/" + String.join(" ", cardsChanged);
return String.join(Character.toString((char) 13), new String[]{
this.getGameId(),
"CHANGED",
change
});
}
private String formatRevealCardsUpdate(Player player) {
return String.join("/", new String[] {
String.join(",", this.playerChanges.containsKey(player) ? "1" : "0", Integer.toString(this.playerChanges.getOrDefault(player, new String[]{}).length)),
String.join("/", this.playerCards.get(player))
});
}
private void disconnectPlayer(Player player) {
if (!this.playersInGame.contains(player))
return;
this.playersInGame.remove(player);
this.playersPlaying.remove(player);
this.playerChanges.remove(player);
this.playerCards.remove(player);
ITEMMSG itemMessage = new ITEMMSG(String.join(Character.toString((char) 13),
this.getGameId(),
"OPPONENT_LOGOUT",
player.getDetails().getName()
));
for (Player p : this.playersInGame)
p.send(itemMessage);
}
private void broadcastOpponents() {
for (Player player: this.playersInGame) {
this.broadcastOpponents(player);
}
}
private void broadcastOpponents(Player player) {
List<String> opponentData = new ArrayList<>();
opponentData.add(player.getDetails().getName() + " " + Integer.toString(this.playerChanges.getOrDefault(player, new String[]{}).length));
for (Player p: this.playersInGame) {
if (p == player)
continue;
opponentData.add(p.getDetails().getName() + " " + Integer.toString(this.playerChanges.getOrDefault(p, new String[]{}).length));
}
player.send(new ITEMMSG(new String[]{this.getGameId(), "OPPONENTS", String.join(Character.toString((char) 13), opponentData)}));
}
private void revealCards() {
// Reveal cards to everyone
List<String> playerUpdates = new ArrayList<>();
for (Player player : this.playersPlaying)
playerUpdates.add(player.getDetails().getName() + "/" + this.formatRevealCardsUpdate(player));
this.sendToPlaying(new ITEMMSG(new String[]{
this.getGameId(),
"REVEALCARDS",
String.join(Character.toString((char) 13), playerUpdates)
}));
}
private void endRound() {
this.options.onFinish(playerCards);
this.revealCards();
this.clearRound();
}
private void clearRound() {
this.options.clear();
this.deck.clear();
this.playerCards.clear();
this.playerChanges.clear();
this.playersPlaying.clear();
}
private List<Player> getDisconnectedPlayers() {
List<Player> toDisconnect = new ArrayList<>();
for (Player player: this.playersInGame) {
if (!this.getPlayers().contains(player))
toDisconnect.add(player);
}
return toDisconnect;
}
private boolean isRoundRunning() {
return !this.deck.isEmpty();
}
private boolean hasEveryoneChanged() {
return this.playersPlaying.stream().filter(p -> this.playerChanges.containsKey(p)).count() == this.playersPlaying.size();
}
/**
* Send message to all players in game (including sender)
* @param messageComposer
*/
public void sendToPlaying(MessageComposer messageComposer) {
for (Player p : this.playersPlaying) {
p.send(messageComposer);
}
}
/**
* Send message to all opponents in game (excluding sender)
* @param sender sender
* @param messageComposer
*/
public void sentToPlayingOpponents(Player sender, MessageComposer messageComposer) {
for (Player p : this.playersPlaying) {
if (p == sender)
continue;
p.send(messageComposer);
}
}
@Override
public int getMaximumPeopleRequired() {
return 4;
@ -41,7 +295,7 @@ public class GamePoker extends GamehallGame {
@Override
public int getMinimumPeopleRequired() {
return 2;
return 1;
}
@Override

View file

@ -44,6 +44,7 @@ public class GameTicTacToe extends GamehallGame {
this.gameMap = null;
}
/*
@Override
public void joinGame(Player p) { }
@ -51,7 +52,7 @@ public class GameTicTacToe extends GamehallGame {
public void leaveGame(Player player) {
this.playerSides.remove(player);
}
*/
@Override
public void handleCommand(Player player, Room room, Item item, String command, String[] args) {
GameTrigger trigger = (GameTrigger) item.getDefinition().getInteractionType().getTrigger();

View file

@ -49,17 +49,11 @@ public abstract class GamehallGame {
*/
public abstract void handleCommand(Player player, Room room, Item item, String command, String[] args);
/**
* Join game handler for player
* @param player the player that join
*/
public abstract void joinGame(Player player);
/**
* Leave game handler for player
* @param player the player that leaves
*/
public abstract void leaveGame(Player player);
// public abstract void leaveGame(Player player);
/**
* Gets the unique game ID instance for this pair. Will

View file

@ -0,0 +1,107 @@
package org.alexdev.havana.game.games.gamehalls.utils;
import java.util.*;
import java.util.stream.Collectors;
public enum GamePokerCombination {
FIVE_OF_A_KIND("a Five of a kind"),
ROYAL_FLUSH("a Royal flush"),
STRAIGHT_FLUSH("a Straight flush"),
FOUR_OF_A_KIND("a Four of a kind"),
FULL_HOUSE("a Full House"),
FLUSH("a Flush"),
STRAIGHT("a Straight"),
THREE_OF_A_KIND("a Three of a kind"),
TWO_PAIR("two pairs"),
ONE_PAIR("one pair"),
HIGH_CARD("an high card");
final static List<String> Faces = Arrays.asList("2","3","4","5","6","7","8","9","10", "11", "12", "13", "1");
final static List<String> Suits = Arrays.asList("h", "d", "c", "s");
final static String Joker = "joker";
private final String name;
GamePokerCombination(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public int getCombinationRank() {
return Math.abs(this.ordinal() - 10);
}
public static List<String> getDeck() {
List<String> deck = new ArrayList<>(Arrays.asList(Joker, Joker));
for (String suit : Suits) {
for (String face : Faces) {
deck.add(suit + face);
}
}
return deck;
}
public static GamePokerCombination getCombination(List<String> hand) {
List<String> cards = hand.stream()
.filter(card -> !card.equals(Joker))
.collect(Collectors.toList());
int jokers = hand.size() - cards.size();
List<Integer> suits = cards.stream()
.map(card -> Suits.indexOf(card.substring(0, 1)))
.collect(Collectors.toList());
List<Integer> faces = cards.stream()
.map(card -> Faces.indexOf(card.substring(1)))
.collect(Collectors.toList());
if (cards.stream().anyMatch(card -> Collections.frequency(cards, card) > 1) ||
faces.stream().anyMatch(face -> face == -1) ||
suits.stream().anyMatch(suit -> suit == -1)) {
return null;
}
boolean flush = suits.stream().allMatch(suit -> suit.equals(suits.get(0)));
List<Integer> groups = Faces.stream()
.map(face -> Collections.frequency(faces, Faces.indexOf(face)))
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
List<Integer> shifted = faces.stream()
.map(face -> (face + 1) % 13)
.collect(Collectors.toList());
int distance = Math.min(Collections.max(faces) - Collections.min(faces),
Collections.max(shifted) - Collections.min(shifted));
boolean straight = groups.get(0) == 1 && distance < 5;
boolean royal = straight && flush && !faces.stream().anyMatch(face -> face < 8);
groups.set(0, groups.get(0) + jokers);
if (groups.get(0) == 5) {
return GamePokerCombination.FIVE_OF_A_KIND;
} else if (royal) {
return GamePokerCombination.ROYAL_FLUSH;
} else if (straight && flush) {
return GamePokerCombination.STRAIGHT_FLUSH;
} else if (groups.get(0) == 4) {
return GamePokerCombination.FOUR_OF_A_KIND;
} else if (groups.get(0) == 3 && groups.get(1) == 2) {
return GamePokerCombination.FULL_HOUSE;
} else if (flush) {
return GamePokerCombination.FLUSH;
} else if (straight) {
return GamePokerCombination.STRAIGHT;
} else if (groups.get(0) == 3) {
return GamePokerCombination.THREE_OF_A_KIND;
} else if (groups.get(0) == 2 && groups.get(1) == 2) {
return GamePokerCombination.TWO_PAIR;
} else if (groups.get(0) == 2) {
return GamePokerCombination.ONE_PAIR;
} else {
return GamePokerCombination.HIGH_CARD;
}
}
}

View file

@ -0,0 +1,265 @@
package org.alexdev.havana.game.games.gamehalls.utils;
import org.alexdev.havana.dao.mysql.CurrencyDao;
import org.alexdev.havana.game.catalogue.CatalogueItem;
import org.alexdev.havana.game.catalogue.CatalogueManager;
import org.alexdev.havana.game.games.gamehalls.GamePoker;
import org.alexdev.havana.game.player.Player;
import org.alexdev.havana.messages.outgoing.rooms.user.CHAT_MESSAGE;
import org.alexdev.havana.messages.outgoing.user.currencies.CREDIT_BALANCE;
import org.alexdev.havana.messages.outgoing.user.currencies.TICKET_BALANCE;
import org.alexdev.havana.util.DateUtil;
import org.alexdev.havana.util.config.GameConfiguration;
import org.apache.commons.lang3.tuple.Pair;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
public class GamePokerOptions {
final private GameConfiguration configuration = GameConfiguration.getInstance();
final private GamePoker room;
final private int entryPrice;
final private int minPlayers;
final private boolean redistributeEntry;
final private boolean redistributeOnTie;
final private int creditsBonus;
final private boolean creditsBonusOnTie;
final private String[] raresReward;
final private int raresQuantity;
final private boolean raresOnTie;
final private int ticketsReward;
final private boolean ticketsOnTie;
final private boolean announceWinner;
final private boolean announceRewards;
// Stateful - will reset every round
private int entryPaid = 0;
final private List<String> rewardMessages = new ArrayList<>();
public GamePokerOptions(GamePoker room) {
this.room = room;
this.entryPrice = this.getInteger("poker.entry.price", 0);
this.minPlayers = this.getInteger("poker.reward.min.player", 2);
this.redistributeEntry = this.getBoolean("poker.entry.price.redistribute", true);
this.redistributeOnTie = this.getBoolean("poker.entry.price.redistribute.on.tie", true);
this.creditsBonus = this.getInteger("poker.reward.credits.bonus", 0);
this.creditsBonusOnTie = this.getBoolean("poker.reward.credits.bonus.on.tie", false);
this.raresReward = this.getString("poker.reward.rares", "").split(",");
this.raresQuantity = this.getInteger("poker.reward.rares.quantity", 0);
this.raresOnTie = this.getBoolean("poker.reward.rares.on.tie", false);
this.ticketsReward = this.getInteger("poker.reward.tickets", 0);
this.ticketsOnTie = this.getBoolean("poker.reward.tickets.on.tie", false);
this.announceWinner = this.getBoolean("poker.announce.winner", true);
this.announceRewards = this.getBoolean("poker.announce.rewards", false);
}
public void onEntry(Player player) {
if (this.entryPrice <= 0)
return;
CurrencyDao.decreaseCredits(player.getDetails(), this.entryPrice);
player.send(new CREDIT_BALANCE(player.getDetails().getCredits()));
this.entryPaid += this.entryPrice;
}
public void clear() {
this.entryPaid = 0;
this.rewardMessages.clear();
}
public void onFinish(Map<Player, List<String>> _players) {
List<Player> playing = _players.keySet().stream().collect(Collectors.toList());
Pair<GamePokerCombination, List<Player>> winners = this.getWinners(_players);
GamePokerCombination winningCombination = winners.getLeft();
List<Player> winnerList = winners.getRight();
if (this.announceWinner)
this.showChat(playing, this.getWinnerMessage(winningCombination, winnerList));
if (playing.size() < this.minPlayers || !this.canReward(winnerList))
return;
this.rewardCredits(winnerList);
this.rewardRares(winnerList);
this.rewardTickets(winnerList);
if (this.announceRewards)
this.rewardMessages.forEach(msg -> this.showChat(playing, msg));
}
private void rewardCredits(List<Player> winners) {
int credits = 0;
if (this.redistributeEntry && (winners.size() == 1 || this.redistributeOnTie))
credits += this.entryPaid;
if (this.creditsBonus > 0 && (winners.size() == 1 || this.creditsBonusOnTie))
credits += this.creditsBonus;
if (credits == 0)
return;
int creditsPerWinner = (int) Math.floor(credits / winners.size());
for (Player winner : winners) {
CurrencyDao.increaseCredits(winner.getDetails(), creditsPerWinner);
winner.send(new CREDIT_BALANCE(winner.getDetails().getCredits()));
}
if (winners.size() > 1)
this.rewardMessages.add("Each winner received " + creditsPerWinner + " credits!");
else
this.rewardMessages.add(winners.get(0).getDetails().getName() + " received " + creditsPerWinner + " credits!");
}
private void rewardRares(List<Player> winners) {
if (this.raresReward.length == 0 || this.raresQuantity == 0 || (winners.size() > 1 && !this.raresOnTie))
return;
CatalogueManager catalogue = CatalogueManager.getInstance();
CatalogueItem[] rares = new CatalogueItem[this.raresQuantity];
String[] rareNames = new String[this.raresQuantity];
for (int i = 0; i < this.raresQuantity; i++) {
int randomIndex = ThreadLocalRandom.current().nextInt(0, this.raresReward.length);
CatalogueItem rare = catalogue.getCatalogueItem(this.raresReward[randomIndex]);
rares[i] = rare;
rareNames[i] = rare.getDefinition().getName();
}
for (Player winner : winners) {
for (CatalogueItem rare : rares) {
try {
catalogue.purchase(winner.getDetails(), rare, null, null, DateUtil.getCurrentTimeSeconds());
} catch (SQLException e) {
// todo: handle exception
e.printStackTrace();
return;
}
}
winner.getInventory().getView("new");
// winner.send(new ITEM_DELIVERED());
}
if (winners.size() > 1)
this.rewardMessages.add("Each winner received " + String.join(", ", rareNames) + " !");
else
this.rewardMessages.add(winners.get(0).getDetails().getName() + " received " + String.join(", ", rareNames) + " !");
}
private void rewardTickets(List<Player> winners) {
if (this.ticketsReward <= 0 || (winners.size() > 1 && !this.ticketsOnTie))
return;
for (Player winner : winners) {
CurrencyDao.increaseTickets(winner.getDetails(), this.ticketsReward);
winner.send(new TICKET_BALANCE(winner.getDetails().getTickets()));
}
if (winners.size() > 1)
this.rewardMessages.add("Each winner received " + this.ticketsReward + " tickets!");
else
this.rewardMessages.add(winners.get(0).getDetails().getName() + " received " + this.ticketsReward + " tickets!");
}
/**
* Show chat message to all players in game
* @param chat
*/
private void showChat(List<Player> players, String chat) {
for (Player p : players) {
p.send(new CHAT_MESSAGE(CHAT_MESSAGE.ChatMessageType.CHAT, p.getRoomUser().getInstanceId(), chat, 0));
}
}
/**
* Does the option apply to the current room?
* @param option
* @return
*/
private boolean activeInRoom(String option) {
String rooms = this.configuration.getString(option + ".only.in.rooms", "");
return rooms.isBlank() || rooms.contains(Integer.toString(this.room.getRoomId()));
}
private String getString(String name, String def) {
String value = this.configuration.getString(name, def);
if (!this.activeInRoom(name))
return def;
return value;
}
private int getInteger(String name, int def) {
int value = this.configuration.getInteger(name);
if (!this.activeInRoom(name))
return def;
return value;
}
private boolean getBoolean(String name, boolean def) {
boolean value = this.configuration.getBoolean(name);
if (!this.activeInRoom(name))
return def;
return value;
}
private boolean canReward(List<Player> winners) {
boolean isTie = winners.size() > 1;
return (
(this.redistributeEntry && this.entryPaid > 0 && (!isTie || this.redistributeOnTie)) ||
(this.raresReward.length > 0 && (!isTie || this.raresOnTie)) ||
(this.ticketsReward > 0 && (!isTie || this.ticketsOnTie)) ||
(this.creditsBonus > 0 && (!isTie || this.creditsBonusOnTie))
);
}
private String getWinnerMessage(GamePokerCombination combination, List<Player> winners) {
if (winners.size() == 1) {
String name = winners.get(0).getDetails().getName();
return name + " wins this round with " + combination.getName() + ". Congratulations!";
} else {
String names = String.join(", ", winners.stream().map(p -> p.getDetails().getName()).collect(Collectors.toList()));
return "It's a tie! " + names + " all have " + combination.getName() + ". Congratulations!";
}
}
private Pair<GamePokerCombination, List<Player>> getWinners(Map<Player, List<String>> players) {
List<Player> winners = new ArrayList<>();
GamePokerCombination winningCombination = null;
// Calculate winners
for (Player player : players.keySet()) {
List<String> hand = players.get(player);
GamePokerCombination combination = GamePokerCombination.getCombination(hand);
if (winningCombination == null) {
winningCombination = combination;
winners.add(player);
continue;
}
if (combination.getCombinationRank() > winningCombination.getCombinationRank()) {
winningCombination = combination;
winners.clear();
winners.add(player);
} else if (combination.getCombinationRank() == winningCombination.getCombinationRank()) {
winners.add(player);
}
}
return Pair.of(winningCombination, winners);
}
}

View file

@ -5,15 +5,40 @@ import org.alexdev.havana.server.netty.streams.NettyResponse;
public class ITEMMSG extends MessageComposer {
private final String[] commands;
private final boolean delimitate;
/**
* Create a new ITEMMSG with multiple commands.
* Each line will be delimited with '\r'
* @param commands
*/
public ITEMMSG(String[] commands) {
this.commands = commands;
this.delimitate = true;
}
/**
* Create a new ITEMMSG with a single command.
* This expects the command to be already delimited
* @param command
*/
public ITEMMSG(String command) {
this.commands = new String[]{command};
this.delimitate = false;
}
@Override
public void compose(NettyResponse response) {
response.write(String.join(Character.toString((char)13), this.commands));
for (String value : this.commands) {
if (this.delimitate) {
response.write(value, '\r');
response.write('\r');
}
else {
response.write(value);
}
}
}
@Override
public short getHeader() {

View file

@ -139,6 +139,34 @@ public class GameConfigWriter implements ConfigWriter {
config.put("messenger.enable.official.update.speed", "false");
config.put("poker.entry.price", "0");
config.put("poker.entry.price.only.in.rooms", "");
config.put("poker.entry.price.redistribute", "true");
config.put("poker.entry.price.redistribute.on.tie", "true");
config.put("poker.entry.price.redistribute.only.in.rooms", "");
config.put("poker.reward.min.player", "2");
config.put("poker.reward.min.player.only.in.rooms", "");
config.put("poker.reward.credits.bonus", "0");
config.put("poker.reward.credits.bonus.on.tie", "false");
config.put("poker.reward.credits.bonus.only.in.rooms", "");
config.put("poker.reward.rares", "");
config.put("poker.reward.rares.only.in.rooms", "");
config.put("poker.reward.rares.quantity", "1");
config.put("poker.reward.rares.on.tie", "false");
config.put("poker.reward.tickets", "0");
config.put("poker.reward.tickets.on.tie", "false");
config.put("poker.reward.tickets.only.in.rooms", "");
config.put("poker.announce.winner", "false");
config.put("poker.announce.winner.only.in.rooms", "0");
config.put("poker.announce.rewards", "false");
config.put("poker.announce.rewards.only.in.rooms", "");
for (var set : CommandManager.getCommands()) {
if (set.getValue().getPlayerRank().getRankId() > 1) {
config.put("groups.ids.permission." + set.getKey()[0], "");