Changed action cards logic.

This commit is contained in:
Michael Wain 2025-04-12 04:22:19 +03:00
parent 729e259b33
commit 3592547afe
16 changed files with 117 additions and 208 deletions

View File

@ -85,11 +85,6 @@
<artifactId>telegrambots-abilities</artifactId> <artifactId>telegrambots-abilities</artifactId>
<version>6.7.0</version> <version>6.7.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.luaj</groupId>
<artifactId>luaj-jse</artifactId>
<version>3.0.1</version>
</dependency>
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-math3</artifactId> <artifactId>commons-math3</artifactId>

View File

@ -53,4 +53,9 @@ public interface Constants {
String INFO_MESSAGE = "Вот открытая информация о живых игроках\n"; String INFO_MESSAGE = "Вот открытая информация о живых игроках\n";
String CANT_SEND_NOT_DAY = "Нельзя использовать эту команду во время перерыва."; String CANT_SEND_NOT_DAY = "Нельзя использовать эту команду во время перерыва.";
String BUNKER_STATS = "В вашем бункере следующая ситуация:\n%s";
String RANDOM_HIV = "Затмение венеры (рандомный вич)";
String RANDOM_HIV_ENABLED = "Венера взошла для игрока %s";
String CHANGE_WORKS = "Обменяться профессиями";
String CHANGE_WORKS_TRIGGERED = "Вы обменялись профессиями с игроком %s";
} }

View File

@ -1,5 +1,6 @@
package com.alterdekim.javabot.bot; package com.alterdekim.javabot.bot;
import com.alterdekim.javabot.bot.cards.ActionCard;
import com.alterdekim.javabot.entities.*; import com.alterdekim.javabot.entities.*;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
@ -25,7 +26,7 @@ public class Player {
private String firstName; private String firstName;
private InfoSections infoSections; private InfoSections infoSections;
private Boolean isVoted = false; private Boolean isVoted = false;
private List<ActionScript> scripts; private List<Class<? extends ActionCard>> scripts;
private Integer scriptMessageId; private Integer scriptMessageId;
public Player(Long telegramId, String name) { public Player(Long telegramId, String name) {

View File

@ -0,0 +1,18 @@
package com.alterdekim.javabot.bot.cards;
import com.alterdekim.javabot.bot.Player;
import com.alterdekim.javabot.components.BunkerBot;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
@AllArgsConstructor
@NoArgsConstructor
public abstract class ActionCard {
BunkerBot bot;
Player activator;
public abstract void execute();
public abstract String getName();
}

View File

@ -0,0 +1,23 @@
package com.alterdekim.javabot.bot.cards;
import com.alterdekim.javabot.Constants;
import com.alterdekim.javabot.bot.Player;
import com.alterdekim.javabot.entities.Work;
import com.alterdekim.javabot.util.BotUtils;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
public class ChangeWorksCard extends ActionCard {
@Override
public void execute() {
Player p = (Player) BotUtils.getRandomFromList(this.bot.players, this.bot.random);
Work w = this.activator.getWork();
this.activator.setWork(p.getWork());
p.setWork(w);
this.bot.sendApi(new SendMessage(this.activator.getTelegramId()+"", String.format(Constants.CHANGE_WORKS_TRIGGERED, p.getFirstName())));
}
@Override
public String getName() {
return Constants.CHANGE_WORKS;
}
}

View File

@ -0,0 +1,22 @@
package com.alterdekim.javabot.bot.cards;
import com.alterdekim.javabot.Constants;
import com.alterdekim.javabot.bot.Player;
import com.alterdekim.javabot.util.BotUtils;
import org.telegram.telegrambots.meta.api.methods.send.SendMessage;
public class RandomHIVCard extends ActionCard {
private static final long HIV_ID = 31;
@Override
public void execute() {
Player p = (Player) BotUtils.getRandomFromList(this.bot.players, this.bot.random);
p.setHealth(this.bot.healthService.getHealthById(HIV_ID));
this.bot.sendApi(new SendMessage(this.activator.getTelegramId()+"", String.format(Constants.RANDOM_HIV_ENABLED, p.getFirstName())));
}
@Override
public String getName() {
return Constants.RANDOM_HIV;
}
}

View File

@ -4,14 +4,14 @@ import com.alterdekim.javabot.bot.*;
import com.alterdekim.javabot.Commands; import com.alterdekim.javabot.Commands;
import com.alterdekim.javabot.Constants; import com.alterdekim.javabot.Constants;
import com.alterdekim.javabot.TelegramConfig; import com.alterdekim.javabot.TelegramConfig;
import com.alterdekim.javabot.bot.cards.ActionCard;
import com.alterdekim.javabot.bot.cards.ChangeWorksCard;
import com.alterdekim.javabot.bot.cards.RandomHIVCard;
import com.alterdekim.javabot.entities.*; import com.alterdekim.javabot.entities.*;
import com.alterdekim.javabot.service.*; import com.alterdekim.javabot.service.*;
import com.alterdekim.javabot.util.*; import com.alterdekim.javabot.util.*;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.JsePlatform;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.telegram.telegrambots.bots.TelegramLongPollingBot; import org.telegram.telegrambots.bots.TelegramLongPollingBot;
@ -44,19 +44,19 @@ public class BunkerBot extends TelegramLongPollingBot {
private double last_p = -1; private double last_p = -1;
private List<Player> players; public List<Player> players;
private final BioService bioService; private final BioService bioService;
private final HealthService healthService; public final HealthService healthService;
private final HobbyService hobbyService; private final HobbyService hobbyService;
private final LuggageService luggageService; private final LuggageService luggageService;
private final WorkService workService; private final WorkService workService;
private final TextDataValService textDataValService; private final TextDataValService textDataValService;
private final DisasterService disasterService; private final DisasterService disasterService;
private final SynergyService synergyService; private final SynergyService synergyService;
private final ActionScriptsServiceImpl scriptsService; private List<Class<? extends ActionCard>> actionCards;
private final RandomComponent random; public final RandomComponent random;
private DayNightFields dayNightFields; private DayNightFields dayNightFields;
@ -72,7 +72,6 @@ public class BunkerBot extends TelegramLongPollingBot {
TextDataValService textDataValService, TextDataValService textDataValService,
DisasterService disasterService, DisasterService disasterService,
SynergyService synergyService, SynergyService synergyService,
ActionScriptsServiceImpl scriptsService,
RandomComponent randomComponent) { RandomComponent randomComponent) {
this.telegramConfig = telegramConfig; this.telegramConfig = telegramConfig;
this.players = new ArrayList<>(); this.players = new ArrayList<>();
@ -85,7 +84,7 @@ public class BunkerBot extends TelegramLongPollingBot {
this.textDataValService = textDataValService; this.textDataValService = textDataValService;
this.disasterService = disasterService; this.disasterService = disasterService;
this.synergyService = synergyService; this.synergyService = synergyService;
this.scriptsService = scriptsService; this.actionCards = List.of(RandomHIVCard.class, ChangeWorksCard.class);
this.random = randomComponent; this.random = randomComponent;
this.dayNightFields = new DayNightFields(); this.dayNightFields = new DayNightFields();
this.linkedQueue = new ConcurrentLinkedQueue<>(); this.linkedQueue = new ConcurrentLinkedQueue<>();
@ -180,7 +179,7 @@ public class BunkerBot extends TelegramLongPollingBot {
private void startGame() { private void startGame() {
if( gameState != GameState.JOINING ) if( gameState != GameState.JOINING )
return; return;
if(players.size() < 2) { // TODO: change to 2 if(players.size() < 1) { // TODO: change to 2
sendApi(new SendMessage(groupId, Constants.PLAYERS_LESS_THAN_ZERO)); sendApi(new SendMessage(groupId, Constants.PLAYERS_LESS_THAN_ZERO));
return; return;
} }
@ -188,12 +187,12 @@ public class BunkerBot extends TelegramLongPollingBot {
this.gameState = GameState.STARTED; this.gameState = GameState.STARTED;
Disaster d = (Disaster) BotUtils.getRandomFromList(disasterService.getAllDisasters(), random); Disaster d = (Disaster) BotUtils.getRandomFromList(disasterService.getAllDisasters(), random);
sendApi(new SendMessage(groupId, getStringById(d.getDescTextId()))); sendApi(new SendMessage(groupId, getStringById(d.getDescTextId())));
//sendApi(new SendMessage(groupId, String.format(Constants.BUNKER_STATS, )));
List<Bio> bios = bioService.getAllBios(); List<Bio> bios = bioService.getAllBios();
List<Work> works = workService.getAllWorks(); List<Work> works = workService.getAllWorks();
List<Luggage> luggs = luggageService.getAllLuggages(); List<Luggage> luggs = luggageService.getAllLuggages();
List<Hobby> hobbies = hobbyService.getAllHobbies(); List<Hobby> hobbies = hobbyService.getAllHobbies();
List<Health> healths = healthService.getAllHealth(); List<Health> healths = healthService.getAllHealth();
List<ActionScript> scripts = scriptsService.getAllActionScripts();
for( int i = 0; i < players.size(); i++ ) { for( int i = 0; i < players.size(); i++ ) {
players.get(i).setAge(random.nextInt(57)+18); players.get(i).setAge(random.nextInt(57)+18);
players.get(i).setGender((Bio) BotUtils.getRandomFromList(bios, random)); players.get(i).setGender((Bio) BotUtils.getRandomFromList(bios, random));
@ -201,13 +200,12 @@ public class BunkerBot extends TelegramLongPollingBot {
players.get(i).setLuggage((Luggage) BotUtils.getRandomFromList(luggs, random)); players.get(i).setLuggage((Luggage) BotUtils.getRandomFromList(luggs, random));
players.get(i).setHobby((Hobby) BotUtils.getRandomFromList(hobbies, random)); players.get(i).setHobby((Hobby) BotUtils.getRandomFromList(hobbies, random));
players.get(i).setHealth((Health) BotUtils.getRandomFromList(healths, random)); players.get(i).setHealth((Health) BotUtils.getRandomFromList(healths, random));
if( (random.nextInt(100) >= 45 || (i == (players.size()-1) && isNoOneHasScripts())) && !scripts.isEmpty() ) { if( (random.nextInt(100) >= 45 || (i == (players.size()-1) && isNoOneHasScripts())) && !this.actionCards.isEmpty() ) {
ActionScript asc = (ActionScript) BotUtils.getRandomFromList(scripts, random); Class<? extends ActionCard> asc = (Class<? extends ActionCard>) BotUtils.getRandomFromList(this.actionCards, random);
//ActionScript asc = scripts.get(scripts.size()-1); this.actionCards.removeIf(p -> p.getCanonicalName().equals(asc.getCanonicalName()));
scripts.removeIf(p -> p.getId().longValue() == asc.getId().longValue());
players.get(i).setScripts(Collections.singletonList(asc)); players.get(i).setScripts(Collections.singletonList(asc));
} else { } else {
players.get(i).setScripts(new ArrayList<>()); players.get(i).setScripts(Collections.emptyList());
} }
} }
doNight(); doNight();
@ -226,7 +224,7 @@ public class BunkerBot extends TelegramLongPollingBot {
sendApi(sendMessage); sendApi(sendMessage);
if( p.getScripts().isEmpty() ) continue; if( p.getScripts().isEmpty() ) continue;
sendMessage = new SendMessage(p.getTelegramId()+"", Constants.SCRIPT_MESSAGE); sendMessage = new SendMessage(p.getTelegramId()+"", Constants.SCRIPT_MESSAGE);
sendMessage.setReplyMarkup(BotUtils.getScriptKeyboard(p.getScripts(), textDataValService)); sendMessage.setReplyMarkup(BotUtils.getScriptKeyboard(p.getScripts()));
try { try {
setScriptMessageId(p, sendApiMethod(sendMessage).getMessageId()); setScriptMessageId(p, sendApiMethod(sendMessage).getMessageId());
} catch (Exception e) { } catch (Exception e) {
@ -247,8 +245,16 @@ public class BunkerBot extends TelegramLongPollingBot {
} }
private void processNightScriptButton(Player p, CallbackQuery callbackQuery, String data) { private void processNightScriptButton(Player p, CallbackQuery callbackQuery, String data) {
ActionScript script = p.getScripts().stream() Class<? extends ActionCard> script = p.getScripts().stream()
.filter(s -> HashUtils.getCRC32(textDataValService.getTextDataValById(s.getTextNameId()).getText().getBytes()).equals(data)) .filter(s -> {
try {
return HashUtils.getCRC32(s.getDeclaredConstructor().newInstance().getName().getBytes()).equals(data);
} catch (Exception e) {
log.error(e.getMessage());
}
return false;
}
)
.findFirst() .findFirst()
.orElse(null); .orElse(null);
if( script == null ) return; if( script == null ) return;
@ -256,24 +262,11 @@ public class BunkerBot extends TelegramLongPollingBot {
sendApi(new SendMessage(groupId, String.format(Constants.PRESSED_SCRIPT_NIGHT, callbackQuery.getFrom().getFirstName()))); sendApi(new SendMessage(groupId, String.format(Constants.PRESSED_SCRIPT_NIGHT, callbackQuery.getFrom().getFirstName())));
sendApi(new SendMessage(callbackQuery.getMessage().getChatId()+"", Constants.THANK_YOU)); sendApi(new SendMessage(callbackQuery.getMessage().getChatId()+"", Constants.THANK_YOU));
p.setScripts(new ArrayList<>()); p.setScripts(new ArrayList<>());
executeLuaScript(script, p); try {
} script.getDeclaredConstructor(BunkerBot.class, Player.class).newInstance(this, p).execute();
} catch (Exception e) {
private void executeLuaScript(ActionScript script, Player p) { log.error(e.getMessage());
Globals globals = JsePlatform.standardGlobals(); }
globals.set("players", LuaSerializer.serializeObjectList(players));
globals.set("player", LuaSerializer.serializeObject(p));
globals.set("genders", LuaSerializer.serializeObjectList(bioService.getAllBios()));
globals.set("hobbies", LuaSerializer.serializeObjectList(hobbyService.getAllHobbies()));
globals.set("healths", LuaSerializer.serializeObjectList(healthService.getAllHealth()));
globals.set("luggages", LuaSerializer.serializeObjectList(luggageService.getAllLuggages()));
globals.set("works", LuaSerializer.serializeObjectList(workService.getAllWorks()));
LuaValue chunk = globals.load(script.getScriptBody());
chunk.call();
this.players = LuaDeserializer.deserializePlayers(globals.get("players"))
.stream()
.peek(p1 -> p1.setScripts(getPlayerById(p1.getTelegramId()).getScripts()))
.collect(Collectors.toList());
} }
private void processNightButton(CallbackQuery callbackQuery) { private void processNightButton(CallbackQuery callbackQuery) {
@ -333,7 +326,7 @@ public class BunkerBot extends TelegramLongPollingBot {
} }
} }
private void sendApi(BotApiMethod<? extends Serializable> method) { public void sendApi(BotApiMethod<? extends Serializable> method) {
this.linkedQueue.add(method); this.linkedQueue.add(method);
} }

View File

@ -1,32 +0,0 @@
package com.alterdekim.javabot.entities;
import jakarta.persistence.*;
import lombok.*;
@ToString
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "action_scripts")
public class ActionScript {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private Long textNameId;
@Column(nullable = false)
private Long textDescId;
@Column(nullable = false)
private String scriptBody;
public ActionScript(Long textNameId, Long textDescId, String scriptBody) {
this.textNameId = textNameId;
this.textDescId = textDescId;
this.scriptBody = scriptBody;
}
}

View File

@ -1,34 +0,0 @@
package com.alterdekim.javabot.entities;
import jakarta.persistence.*;
import lombok.*;
@ToString
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "action_scripts_req")
public class ActionScriptRequest {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String textName;
@Column(nullable = false)
private String textDesc;
@Column(nullable = false)
private String scriptBody;
public ActionScriptRequest(String textName, String textDesc, String scriptBody) {
this.textName = textName;
this.textDesc = textDesc;
this.scriptBody = scriptBody;
}
}

View File

@ -1,14 +0,0 @@
package com.alterdekim.javabot.repository;
import com.alterdekim.javabot.entities.ActionScript;
import com.alterdekim.javabot.entities.ActionScriptRequest;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.Optional;
public interface ActionScriptRequestsRepository extends JpaRepository<ActionScriptRequest, Long> {
Optional<ActionScriptRequest> findById(Long id);
List<ActionScriptRequest> findAll();
}

View File

@ -1,13 +0,0 @@
package com.alterdekim.javabot.repository;
import com.alterdekim.javabot.entities.ActionScript;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.Optional;
public interface ActionScriptsRepository extends JpaRepository<ActionScript, Long> {
Optional<ActionScript> findById(Long id);
List<ActionScript> findAll();
}

View File

@ -1,13 +0,0 @@
package com.alterdekim.javabot.service;
import com.alterdekim.javabot.entities.ActionScript;
import com.alterdekim.javabot.entities.ActionScriptRequest;
import java.util.List;
public interface ActionRequestService {
List<ActionScriptRequest> getAllActionScripts();
ActionScriptRequest getActionScriptById(long scriptId);
void removeById(long scriptId);
void saveScript(ActionScriptRequest script);
}

View File

@ -1,13 +0,0 @@
package com.alterdekim.javabot.service;
import com.alterdekim.javabot.entities.ActionScript;
import com.alterdekim.javabot.entities.Luggage;
import java.util.List;
public interface ActionScriptsService {
List<ActionScript> getAllActionScripts();
ActionScript getActionScriptById(long scriptId);
void removeById(long scriptId);
void saveScript(ActionScript script);
}

View File

@ -1,35 +0,0 @@
package com.alterdekim.javabot.service;
import com.alterdekim.javabot.entities.ActionScript;
import com.alterdekim.javabot.repository.ActionScriptsRepository;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@AllArgsConstructor
public class ActionScriptsServiceImpl implements ActionScriptsService {
private final ActionScriptsRepository actionScriptsRepository;
@Override
public List<ActionScript> getAllActionScripts() {
return actionScriptsRepository.findAll();
}
@Override
public ActionScript getActionScriptById(long scriptId) {
return actionScriptsRepository.findById(scriptId).orElse(null);
}
@Override
public void removeById(long scriptId) {
actionScriptsRepository.deleteById(scriptId);
}
@Override
public void saveScript(ActionScript script) {
actionScriptsRepository.save(script);
}
}

View File

@ -3,16 +3,17 @@ package com.alterdekim.javabot.util;
import com.alterdekim.javabot.Constants; import com.alterdekim.javabot.Constants;
import com.alterdekim.javabot.bot.InfoSections; import com.alterdekim.javabot.bot.InfoSections;
import com.alterdekim.javabot.bot.SectionType; import com.alterdekim.javabot.bot.SectionType;
import com.alterdekim.javabot.bot.cards.ActionCard;
import com.alterdekim.javabot.components.RandomComponent; import com.alterdekim.javabot.components.RandomComponent;
import com.alterdekim.javabot.entities.ActionScript; import lombok.extern.slf4j.Slf4j;
import com.alterdekim.javabot.service.TextDataValService;
import com.alterdekim.javabot.service.TextDataValServiceImpl;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup; import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup;
import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton; import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton;
import java.lang.reflect.InvocationTargetException;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Slf4j
public class BotUtils { public class BotUtils {
public static InlineKeyboardMarkup getJoinKeyboard() { public static InlineKeyboardMarkup getJoinKeyboard() {
InlineKeyboardMarkup inlineKeyboardMarkup = new InlineKeyboardMarkup(); InlineKeyboardMarkup inlineKeyboardMarkup = new InlineKeyboardMarkup();
@ -77,13 +78,18 @@ public class BotUtils {
return inlineKeyboardMarkup; return inlineKeyboardMarkup;
} }
public static InlineKeyboardMarkup getScriptKeyboard(List<ActionScript> scripts, TextDataValService textDataValService) { public static InlineKeyboardMarkup getScriptKeyboard(List<Class<? extends ActionCard>> scripts) {
InlineKeyboardMarkup inlineKeyboardMarkup = new InlineKeyboardMarkup(); InlineKeyboardMarkup inlineKeyboardMarkup = new InlineKeyboardMarkup();
inlineKeyboardMarkup.setKeyboard(scripts.stream() inlineKeyboardMarkup.setKeyboard(scripts.stream()
.map(s -> { .map(s -> {
InlineKeyboardButton inlineKeyboardButton = new InlineKeyboardButton(); InlineKeyboardButton inlineKeyboardButton = new InlineKeyboardButton();
inlineKeyboardButton.setText(textDataValService.getTextDataValById(s.getTextNameId()).getText()); try {
inlineKeyboardButton.setCallbackData(HashUtils.getCRC32(textDataValService.getTextDataValById(s.getTextNameId()).getText().getBytes())); inlineKeyboardButton.setText(s.getDeclaredConstructor().newInstance().getName());
inlineKeyboardButton.setCallbackData(HashUtils.getCRC32(s.getDeclaredConstructor().newInstance().getName().getBytes()));
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException |
InvocationTargetException e) {
log.error(e.getMessage());
}
return Collections.singletonList(inlineKeyboardButton); return Collections.singletonList(inlineKeyboardButton);
}).collect(Collectors.toList())); }).collect(Collectors.toList()));
return inlineKeyboardMarkup; return inlineKeyboardMarkup;

View File

@ -42,12 +42,12 @@
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/panel?section=stats" th:text="#{stats}"></a> <a class="nav-link" href="/panel?section=stats" th:text="#{stats}"></a>
</li> </li>
<li class="nav-item"> <!--<li class="nav-item">
<a class="nav-link" href="/panel?section=actions" th:text="#{actions}"></a> <a class="nav-link" href="/panel?section=actions" th:text="#{actions}"></a>
</li> </li>-->
<li class="nav-item"> <!--<li class="nav-item">
<a class="nav-link" href="/panel?section=script_request" th:text="#{scrireqq}"></a> <a class="nav-link" href="/panel?section=script_request" th:text="#{scrireqq}"></a>
</li> </li>-->
<li class="nav-item"> <li class="nav-item">
<a class="nav-link" href="/panel?section=themes" th:text="#{themes}"></a> <a class="nav-link" href="/panel?section=themes" th:text="#{themes}"></a>
</li> </li>