lua added

This commit is contained in:
Michael Wain 2024-03-13 17:29:39 +03:00
parent 80572e7e03
commit f6d76fafc6
5 changed files with 169 additions and 3 deletions

View File

@ -1,6 +1,7 @@
package com.alterdekim.javabot;
public interface Constants {
String SCRIPT_MESSAGE = "Вам доступны карты действий:\n";
String REMOVE_PLAYER = "Игрок %s покидает бункер.";
String ENDVOTE = "Голосование окончено.";
String DRAW = "Ничья. Никто не уходит из игры.";
@ -35,6 +36,7 @@ public interface Constants {
String LUGG_MESSAGE = "%s - багаж: %s (%s)";
String DAY_MESSAGE_UPPER = "Следующий раунд начался!\nВероятность выжить \uD83D\uDCC8: %d%% (увеличилась на %f%%)";
String PRESSED_NIGHT = "%s нажал(а)";
String PRESSED_SCRIPT_NIGHT = "%s использовал(а) карту действий";
String DAY_MESSAGE_DOWN = "Следующий раунд начался!\nВероятность выжить \uD83D\uDCC9: %d%% (уменьшилась на %f%%)";
String DAY_MESSAGE = "Следующий раунд начался!\nВероятность выжить: %f%%";
String END_GAME = "Конец игры.\nВероятность выжить: %f%%";

View File

@ -5,6 +5,8 @@ import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter
@Setter
@AllArgsConstructor
@ -20,6 +22,8 @@ public class Player {
private String firstName;
private InfoSections infoSections;
private Boolean isVoted = false;
private List<ActionScript> scripts;
private Integer scriptMessageId;
public Player(Long telegramId, String name) {
this.telegramId = telegramId;

View File

@ -9,8 +9,12 @@ import com.alterdekim.javabot.service.*;
import com.alterdekim.javabot.util.BotUtils;
import com.alterdekim.javabot.util.GameState;
import com.alterdekim.javabot.util.HashUtils;
import com.alterdekim.javabot.util.LuaSerializer;
import jakarta.validation.constraints.NotNull;
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.stereotype.Component;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
@ -27,10 +31,12 @@ import org.telegram.telegrambots.meta.api.objects.User;
import org.telegram.telegrambots.meta.api.objects.chatmember.ChatMember;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import javax.swing.*;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@Component
@Slf4j
@ -52,6 +58,7 @@ public class BunkerBot extends TelegramLongPollingBot {
private final TextDataValService textDataValService;
private final DisasterService disasterService;
private final SynergyService synergyService;
private final ActionScriptsServiceImpl scriptsService;
private final Random random;
@ -68,7 +75,8 @@ public class BunkerBot extends TelegramLongPollingBot {
WorkService workService,
TextDataValService textDataValService,
DisasterService disasterService,
SynergyService synergyService) {
SynergyService synergyService,
ActionScriptsServiceImpl scriptsService) {
this.telegramConfig = telegramConfig;
this.players = new ArrayList<>();
this.gameState = GameState.NONE;
@ -80,12 +88,13 @@ public class BunkerBot extends TelegramLongPollingBot {
this.textDataValService = textDataValService;
this.disasterService = disasterService;
this.synergyService = synergyService;
this.scriptsService = scriptsService;
this.random = new Random();
this.dayNightFields = new DayNightFields();
this.linkedQueue = new ConcurrentLinkedQueue<>();
}
@Scheduled(fixedRate = 100)
@Scheduled(fixedRate = 150)
private void executeApi() {
if( !this.linkedQueue.isEmpty() )
sendApiMethodAsync(this.linkedQueue.poll());
@ -183,6 +192,7 @@ public class BunkerBot extends TelegramLongPollingBot {
List<Luggage> luggs = luggageService.getAllLuggages();
List<Hobby> hobbies = hobbyService.getAllHobbies();
List<Health> healths = healthService.getAllHealth();
List<ActionScript> scripts = scriptsService.getAllActionScripts();
for( Player p : players ) {
p.setAge(random.nextInt(57)+18);
p.setGender((Bio) BotUtils.getRandomFromList(bios, random));
@ -190,7 +200,11 @@ public class BunkerBot extends TelegramLongPollingBot {
p.setLuggage((Luggage) BotUtils.getRandomFromList(luggs, random));
p.setHobby((Hobby) BotUtils.getRandomFromList(hobbies, random));
p.setHealth((Health) BotUtils.getRandomFromList(healths, random));
if( random.nextBoolean() ) {
p.setScripts(Arrays.asList((ActionScript) BotUtils.getRandomFromList(scripts, random)));
} else {
p.setScripts(new ArrayList<>());
}
SendMessage sendMessage = new SendMessage(p.getTelegramId()+"", BotAccountProfileGenerator.build(textDataValService, p));
sendApi(sendMessage);
}
@ -206,13 +220,49 @@ public class BunkerBot extends TelegramLongPollingBot {
SendMessage sendMessage = new SendMessage(p.getTelegramId()+"", Constants.SHOW_TIME);
sendMessage.setReplyMarkup(BotUtils.getShowKeyboard(p.getInfoSections()));
sendApi(sendMessage);
sendMessage = new SendMessage(p.getTelegramId()+"", Constants.SCRIPT_MESSAGE);
sendMessage.setReplyMarkup(BotUtils.getScriptKeyboard(p.getScripts(), textDataValService));
try {
setScriptMessageId(p, sendApiMethod(sendMessage).getMessageId());
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
private void setScriptMessageId(Player p, Integer messageId) {
IntStream.range(0, players.size()).forEach(i -> {
if( players.get(i).getTelegramId().longValue() == p.getTelegramId().longValue() ) {
players.get(i).setScriptMessageId(messageId);
}
});
}
private String getStringById(Long id) {
return textDataValService.getTextDataValById(id).getText();
}
private void processNightScriptButton(Player p, CallbackQuery callbackQuery, String data) {
ActionScript script = p.getScripts().stream()
.filter(s -> textDataValService.getTextDataValById(s.getTextNameId()).getText().equals(data))
.findFirst()
.orElse(null);
if( script == null ) return;
sendApi(new DeleteMessage(callbackQuery.getMessage().getChatId()+"", p.getScriptMessageId()));
sendApi(new SendMessage(groupId, String.format(Constants.PRESSED_SCRIPT_NIGHT, callbackQuery.getFrom().getFirstName())));
sendApi(new SendMessage(callbackQuery.getMessage().getChatId()+"", Constants.THANK_YOU));
p.getScripts().removeIf(s -> s.getId().longValue() == script.getId().longValue());
executeLuaScript(script, p);
}
private void executeLuaScript(ActionScript script, Player p) {
Globals globals = JsePlatform.standardGlobals();
globals.set("players", LuaSerializer.serializeObjectList(players));
globals.set("player", LuaSerializer.serializeObject(p));
LuaValue chunk = globals.load(script.getScriptBody());
chunk.call();
}
private void processNightButton(CallbackQuery callbackQuery) {
if( this.hasPlayerWithId(callbackQuery.getFrom().getId()) &&
!getPlayerById(callbackQuery.getFrom().getId()).getIsAnswered() ) {
@ -254,11 +304,15 @@ public class BunkerBot extends TelegramLongPollingBot {
getStringById(p.getWork().getTextDescId())) + "\n");
ins.setIsWorkShowed(true);
break;
default:
processNightScriptButton(p, callbackQuery, new String(HashUtils.decodeHexString(callbackQuery.getData())));
return;
}
setIsAnswered(callbackQuery.getFrom().getId());
updateInfoSections(p, ins);
sendApi(new SendMessage(callbackQuery.getMessage().getChatId()+"", Constants.THANK_YOU));
sendApi(new DeleteMessage(callbackQuery.getMessage().getChatId()+"", callbackQuery.getMessage().getMessageId()));
sendApi(new DeleteMessage(callbackQuery.getMessage().getChatId()+"", p.getScriptMessageId()));
sendApi(new SendMessage(groupId, String.format(Constants.PRESSED_NIGHT, callbackQuery.getFrom().getFirstName())));
if( isAllAnswered() ) doDay();
}

View File

@ -2,10 +2,14 @@ package com.alterdekim.javabot.util;
import com.alterdekim.javabot.Constants;
import com.alterdekim.javabot.bot.InfoSections;
import com.alterdekim.javabot.entities.ActionScript;
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.buttons.InlineKeyboardButton;
import java.util.*;
import java.util.stream.Collectors;
public class BotUtils {
public static InlineKeyboardMarkup getJoinKeyboard() {
@ -70,6 +74,18 @@ public class BotUtils {
return inlineKeyboardMarkup;
}
public static InlineKeyboardMarkup getScriptKeyboard(List<ActionScript> scripts, TextDataValService textDataValService) {
InlineKeyboardMarkup inlineKeyboardMarkup = new InlineKeyboardMarkup();
inlineKeyboardMarkup.setKeyboard(scripts.stream()
.map(s -> {
InlineKeyboardButton inlineKeyboardButton = new InlineKeyboardButton();
inlineKeyboardButton.setText(textDataValService.getTextDataValById(s.getTextNameId()).getText());
inlineKeyboardButton.setCallbackData(HashUtils.bytesToHex(textDataValService.getTextDataValById(s.getTextNameId()).getText().getBytes()));
return Collections.singletonList(inlineKeyboardButton);
}).collect(Collectors.toList()));
return inlineKeyboardMarkup;
}
public static InlineKeyboardMarkup getGameTypeKeyboard() {
InlineKeyboardMarkup inlineKeyboardMarkup = new InlineKeyboardMarkup();
List<List<InlineKeyboardButton>> columns = new ArrayList<>();

View File

@ -0,0 +1,90 @@
package com.alterdekim.javabot.util;
import com.alterdekim.javabot.bot.Player;
import com.alterdekim.javabot.entities.Bio;
import lombok.extern.slf4j.Slf4j;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
public class LuaSerializer {
public static LuaTable serializeObjectList(List<Player> list) {
LuaTable table = new LuaTable();
list.forEach(o -> table.set(table.length() + 1, serializeObject(o)));
return table;
}
public static LuaValue serializeObject(Object o) {
Map<String, Object> map = new HashMap<>();
getPrivateFields(o.getClass()).stream()
.forEach(f -> {
try {
f.setAccessible(true);
String type_name = ((Class) f.getType()).getName();
String name = f.getName();
switch (type_name) {
case "java.lang.Long":
map.put(name, ((Long) f.get(o)).longValue());
break;
case "long":
map.put(name, f.getLong(o));
break;
case "int":
map.put(name, f.getInt(o));
break;
case "java.lang.Integer":
map.put(name, ((Integer) f.get(o)).intValue());
break;
case "boolean":
map.put(name, f.getBoolean(o));
break;
case "java.lang.Boolean":
map.put(name, ((Boolean) f.get(o)).booleanValue());
break;
case "java.lang.String":
map.put(name, (String) f.get(o));
break;
default:
map.put(name, serializeObject(f.get(o)));
break;
}
} catch (Exception e) {
//log.error(e.getMessage(), e);
}
});
return convert(map);
}
private static LuaValue convert(Map<String, Object> map) {
LuaTable luaTable = new LuaTable();
for (Map.Entry<String, Object> entry : map.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// Convert Java object to LuaValue (handle different data types)
LuaValue luaValue = CoerceJavaToLua.coerce(value);
luaTable.set(key, luaValue);
}
return luaTable;
}
private static List<Field> getPrivateFields(Class<?> theClass) {
List<Field> privateFields = new ArrayList<Field>();
Field[] fields = theClass.getDeclaredFields();
for(Field field : fields){
if(Modifier.isPrivate(field.getModifiers())) {
privateFields.add(field);
}
}
return privateFields;
}
}