我正在制作一个具有2个HashMap的机器人,我需要对其进行序列化和保存。该机器人基本上会为每条消息奖励积分,然后用这笔钱可以建造一座城市。问题是我是这种事情的初学者,我无法弄清楚如何序列化这些HashMap,以及序列化应在代码中的何处进行。 HashMaps的一种是点的类型,另一种是城市的>。任何帮助将不胜感激。
//main class
import com.jagrosh.jdautilities.command.CommandClient;
import com.jagrosh.jdautilities.command.CommandClientBuilder;
import com.jagrosh.jdautilities.commons.waiter.EventWaiter;
import net.dv8tion.jda.core.AccountType;
import net.dv8tion.jda.core.JDA;
import net.dv8tion.jda.core.JDABuilder;
import net.dv8tion.jda.core.entities.Game;
import net.dv8tion.jda.core.hooks.ListenerAdapter;
public class DMain extends ListenerAdapter
{
public static void main(String[] args) throws Exception
{
JDA jda = new JDABuilder(AccountType.BOT).setToken("token").build();
CommandClientBuilder builder = new CommandClientBuilder();
EventWaiter waiter = new EventWaiter();
builder.setOwnerId("OwnerId");
builder.setPrefix("$");
builder.setHelpWord("help");
builder.setGame(Game.listening("$help"));
builder.addCommands(new PointsGetter(), new Build(waiter), new City(), new Upgrade(waiter),new Rename(waiter), new Info(), new Set());
CommandClient client = builder.build();
jda.addEventListener(client);
jda.addEventListener(waiter);
jda.addEventListener(new PointsAdder());
}
}
//classes that pertain to the HashMaps I want to save
//class 1
import java.time.OffsetDateTime;
import java.util.HashMap;
import net.dv8tion.jda.core.entities.User;
import net.dv8tion.jda.core.events.message.MessageReceivedEvent;
import net.dv8tion.jda.core.hooks.ListenerAdapter;
public class PointsAdder extends ListenerAdapter
{
public static HashMap<User, Integer> bal = new HashMap<User, Integer>();
private HashMap<User, OffsetDateTime> coolingDown = new HashMap<User, OffsetDateTime>();
@Override
public void onMessageReceived(MessageReceivedEvent e)
{
if(e.getAuthor().isBot())
return;
if(coolingDown.containsKey(e.getAuthor()))
{
if(e.getMessage().getCreationTime().isAfter(coolingDown.get(e.getAuthor()).plusSeconds(30)))
{
if(e.getMessage().getContentRaw().equalsIgnoreCase("$bal"))
return;
if(bal.containsKey(e.getAuthor()))
{
bal.put(e.getAuthor(), (bal.get(e.getAuthor()) + (1 + (int) (Math.random()*(100 - 90) + 90))));
}
else
bal.put(e.getAuthor(), 100);
coolingDown.put(e.getAuthor(), e.getMessage().getCreationTime());
}
else
return;
}
else
{
if(e.getMessage().getContentRaw().equalsIgnoreCase("$bal"))
return;
if(bal.containsKey(e.getAuthor()))
{
bal.put(e.getAuthor(), (bal.get(e.getAuthor()) + 1 + (int) (Math.random()*((100 - 90) + 90))));
}
else
bal.put(e.getAuthor(), 100);
coolingDown.put(e.getAuthor(), e.getMessage().getCreationTime());
}
}
}
//class 2
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import com.jagrosh.jdautilities.command.Command;
import com.jagrosh.jdautilities.command.CommandEvent;
import com.jagrosh.jdautilities.commons.waiter.EventWaiter;
import net.dv8tion.jda.core.entities.User;
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
public class Build extends Command
{
private final EventWaiter waiter;
public static HashMap<User, ArrayList<Building>> city = new HashMap<User, ArrayList<Building>>();
public Build(EventWaiter w)
{
super.name = "build";
super.help = "Builds a new building in your city.";
super.arguments = "(name your building after requested)";
waiter = w;
}
@Override
protected void execute(CommandEvent event)
{
if(city.containsKey(event.getAuthor()))
{
if(PointsAdder.bal.containsKey(event.getAuthor()))
{
if(PointsAdder.bal.get(event.getAuthor()) >= 1000)
{
event.reply("Ok! Now, give me the name you wish to call you building.");
waiter.waitForEvent(GuildMessageReceivedEvent.class, e -> e.getAuthor().equals(event.getAuthor()) && e.getChannel().equals(event.getChannel()), e -> {
city.get(event.getAuthor()).add(new Building(e.getMessage().getContentDisplay(), 100, 1));
PointsAdder.bal.put(e.getAuthor(), PointsAdder.bal.get(e.getAuthor())-1000);
event.reply(e.getAuthor().getAsMention() + " your building has been built.");
}, 30, TimeUnit.SECONDS, () -> event.reply("You did not give me a name. Try again."));
}
else
event.reply("You do not have sufficient funds to build a buidling.");
}
else
event.reply("You do not have a balance yet.");
}
else
{
if(PointsAdder.bal.containsKey(event.getAuthor()))
{
if(PointsAdder.bal.get(event.getAuthor()) >= 1000)
{
event.reply("Ok! Now, give me the name you wish to call you building.");
waiter.waitForEvent(GuildMessageReceivedEvent.class, e -> e.getAuthor().equals(event.getAuthor()) && e.getChannel().equals(event.getChannel()), e -> {
city.put(e.getAuthor(), new ArrayList<Building>());
city.get(event.getAuthor()).add(new Building(e.getMessage().getContentDisplay(), 100, 1));
PointsAdder.bal.put(e.getAuthor(), PointsAdder.bal.get(e.getAuthor())-1000);
event.reply(e.getAuthor().getAsMention() + " your building has been built.");
}, 30, TimeUnit.SECONDS, () -> event.reply("You did not give me a name. Try again."));
}
else
event.reply("You do not have sufficient funds to build a buidling.");
}
else
event.reply("You do not have a balance yet.");
}
}
}
我希望能够重新启动漫游器,而不丢失所有播放器的数据。
答案 0 :(得分:0)
如果要序列化Hashmap,则类User
应该实现接口Serializeable
。 (class User implements Serializeable
。
之后,您可以将其保存并加载到以下文件中:
保存:save(map,"file");
加载:map=(HashMap<User,Integer>)load("file");
if(map==null) map=new HashMap<>()
public void save(Object toSave,String filename) throws IOException{
new File(filename).createNewFile()//create new file if it does not exist
try(ObjectOutputStream oos=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(filename)))){
oos.writeObject(toSave);
}
}
public Object load(String filename) throws IOException{
try(ObjectInputStream ois=new ObjectInputStream(new BufferedInputStream(new FileInputStream(filename)))){
return ois.readObject();
}
}