-
-
Notifications
You must be signed in to change notification settings - Fork 1
Create Configurations
ELDependenci using ORM to create the configuration, (no more getType)!
name: "hello world"
number: 12
bool: true
box:
name: "box abc"
size: 20
color: RED
can be mapped with
@Resource(locate = "config.yml") // locate your file
public class TestConfig extends Configuration {
public String name;
public int number;
public boolean bool;
public Box box;
public static class Box {
public String name;
public int size;
public ChatColor color;
}
}
then, register in your main class:
@Override
public void bindServices(ServiceCollection serviceCollection) {
serviceCollection.addConfiguration(TestConfig.class); // register config
}
you can inject it into any of your commands, listeners, or any registered singleton and services
examples:
@Commander(
name = "edit",
description = "config edit command"
)
public class TestConfigEditCommand implements CommandNode {
private final Random random = new Random();
@Inject //inject
private TestConfig config;
@Override
public void execute(CommandSender commandSender) {
config.bool = random.nextBoolean();
config.name = UUID.randomUUID().toString();
config.number = random.nextInt();
config.box = new TestConfig.Box();
config.box.color = ChatColor.values()[random.nextInt(ChatColor.values().length)];
config.box.name = UUID.randomUUID().toString()+" box";
config.box.size = random.nextInt();
try {
config.getController().save();
commandSender.sendMessage("save completed");
} catch (IOException e) {
e.printStackTrace();
}
}
}
public class TestListeners implements Listener {
@Inject //inject!
private TestConfig config;
@EventHandler
public void onPlayerChat(AsyncPlayerChatEvent e) {
if (e.getMessage().equals("config")) {
e.getPlayer().sendMessage(config.toString());
}
}
}
the config instance will have a getController()
method, so that you can use the save()
and reload()
method.
to create a configuration that only contains messages, creates a class, and extends LangConfiguration.
assume you have lang.yml
prefix: "&a[Plugin]&r"
hello: "&ahello world!"
bye: "&7good bye!"
then the class will be like:
@Prefix(path = "prefix")
@Resource(locate = "lang.yml")
public class LangConfig extends LangConfiguration {
}
and then register:
@Override
public void bindServices(ServiceCollection serviceCollection) {
serviceCollection.addConfiguration(LangConfig.class);
}
still simple
same as you do in config, inject it.
but instead of using those properties, just calling getLang()
then you will have those methods
/**
* ends with F -> String.format, else, it uses MessageFormat.format
*/
public interface LangController {
String get(String node);
String get(String node, Object... args);
String getF(String node, Object... args);
String getPure(String node);
String getPure(String node, Object... args);
String getPureF(String node, Object... args);
List<String> getList(String node);
List<String> getPureList(String node);
String getPrefix();
}
all have been translated color code automatically.
assume you have a folder structure like this.
YourPlugin/
|- Books
|- normal.yml
|- test.yml
then you can do like this
@GroupResource(folder = "Books")
public class Book extends GroupConfiguration {
public String title;
public String author;
public String description;
public int pages;
public List<String> contents;
}
to copy all resources inside jar into the plugin folder when server starts:
@GroupResource(
folder = "Books",
preloads = { "normal", "test" }
)
public class Book extends GroupConfiguration {
public String title;
public String author;
public String description;
public int pages;
public List<String> contents;
}
the format of the yaml inside that folder must be united:
title: "正常的書名"
author: "正常的作者"
description: "真的很正常的一本書"
pages: 666
contents:
- "這是一本很正常的書本"
- "為什麼我會說很正常呢"
- "因為真的很正常"
- "正常到你察覺不了他的存在"
- "oh 當你看到這則訊息的時候代表他重載得很正常。"
title: "測試書本"
author: "愛測試的作者"
description: "這是一本測試的書"
pages: 9999
contents:
- "測試的重點"
- "就是必須被測試"
- "否則就無法測試"
- "有測試才有實踐"
then register like this in main class:
@Override
public void bindServices(ServiceCollection serviceCollection) {
serviceCollection.addGroupConfiguration(Book.class); //register
}
instead of using @Inject
you need to use @InjectPool
for the group config.
@Commander(
name = "check",
description = "book chceck command"
)
public class TestBookCheckCommand implements CommandNode {
@InjectPool // 使用 @InjectPool 而不是 @Inject
private GroupConfig<Book> bookGroupConfig; // 注入
@CommandArg(order = 0)
private String book;
@Override
public void execute(CommandSender commandSender) {
Optional<Book> gp = bookGroupConfig.findById(book);
if (gp.isEmpty()){
commandSender.sendMessage("book "+book+" is not exist.");
return;
}
var bookContent = gp.get();
commandSender.sendMessage("id: "+bookContent.getId());
commandSender.sendMessage("title: "+ bookContent.title);
commandSender.sendMessage("author: "+bookContent.author);
commandSender.sendMessage("description: "+bookContent.description);
commandSender.sendMessage("total pages: "+bookContent.pages);
commandSender.sendMessage("content: ");
for (int i = 0; i < bookContent.contents.size(); i++) {
commandSender.sendMessage(i+1+": "+bookContent.contents.get(i));
}
}
}
here is the source code for GroupConfig<T>
public interface GroupConfig<T extends GroupConfiguration> {
List<T> findAll();
List<T> findAll(Predicate<Path> filter);
Page<T> findAll(PageRequest pageRequest);
Optional<T> findById(String id);
void save(T config);
boolean deleteById(String id);
long totalSize();
boolean delete(T config);
// like reload (clear cache)
void fetch();
// like reload (clear cache)
void fetchById(String id);
}
you can also create a configuration data at runtime:
@Commander(
name = "add",
description = "add book"
)
public class TestBookAddCommand implements CommandNode {
@InjectPool
private GroupConfig<Book> groupConfig;
@Inject
private ScheduleService scheduleService; // 如需使用異步,請自行實現
@Inject
private ELDTester plugin;
@CommandArg(order = 1)
private String id;
@CommandArg(order = 1, optional = true)
private String author = "unknown";
@Override
public void execute(CommandSender sender) {
Book book = new Book();
book.setId(id); // must set the id
book.title = "This is a title with id "+id;
book.author = author;
book.description = "book with id "+id;
book.contents = Arrays.asList("this", "is", "a", "content");
scheduleService
.runAsync(plugin, () -> groupConfig.save(book))
.thenRunSync(v -> sender.sendMessage("save completed")).join();
}
}
and also do the pagination
@Commander(
name = "page",
description = "pagination test for books"
)
public class TestBookPageCommand implements CommandNode {
// custom filter
private static final Predicate<Path> NO_START_WITH_B = path -> !path.getFileName().toString().startsWith("b");
private static final Predicate<Path> NO_START_WITH_A = path -> !path.getFileName().toString().startsWith("a");
@InjectPool
private GroupConfig<Book> groupConfig;
@Inject
private ScheduleService scheduleService;
@Inject
private ELDTester plugin;
@CommandArg(order = 1)
private int page;
@CommandArg(order = 2, optional = true)
private boolean showContent = false;
@CommandArg(order = 3, optional = true)
private int size = 10;
@Override
public void execute(CommandSender commandSender) {
int index = Math.max(0, page - 1);
groupConfig.fetch(); // reload folders
scheduleService.callAsync(plugin, () -> groupConfig.findAll(PageRequest.of(index, size, NO_START_WITH_B))) // 異步仍然需要自己實現
.thenRunSync(page -> {
commandSender.sendMessage("page size: "+page.getContent().size());
page.getContent().forEach(book -> commandSender.sendMessage(showContent ? book.toString() : book.getId()));
// get the properties below via Page<T>
commandSender.sendMessage(MessageFormat.format("page {0} / {1}, Total Elements: {2}", page.getCurrentPage()+1, page.getTotalPages(), page.getTotalElements()));
}).join();
}
}
assume you have two languages support
Langs/en-us.yml
prefix: "[ELD] "
first: "This is the first message"
second: "This is the second message"
third: "This is the third message"
Langs/zh-tw.yml
prefix: "[ELD] "
first: "這是第一則信息"
second: "這是第二則訊息"
third: "這是第三則信息"
then you can use it like this
@GroupResource(
folder = "Langs", // 語言文件的文件夾
preloads = {"en-us", "zh-tw"} // 複製這兩個文件從 jar 內到 插件資料夾
)
@DefaultLanguage("en-us") // 定義默認語言
@Prefix(path = "prefix") // 定義prefix路徑
public class TesterMultiLang extends GroupLangConfiguration {
}
and register in the main class
@Override
public void bindServices(ServiceCollection serviceCollection) {
serviceCollection.addMultipleLanguages(TesterMultiLang.class); // register multi languages
}
instead of using GroupConfig<T>
from GroupConfiguration, here you will need to use GroupLang<T>
to declare.
@Commander(
name = "lang",
description = "test language command"
)
public class TestLanguageCommand implements CommandNode {
@InjectPool
private GroupLang<TesterMultiLang> multiLangGroupLang;
@CommandArg(order = 1)
private String language;
@Override
public void execute(CommandSender commandSender) {
Optional<TesterMultiLang> multiLangOpt = multiLangGroupLang.getByLocale(language);
if (multiLangOpt.isEmpty()){
commandSender.sendMessage("unknown language");
return;
}
var multiLang = multiLangOpt.get();
commandSender.sendMessage(multiLang.getLang().get("first"));
commandSender.sendMessage(multiLang.getLang().get("second"));
commandSender.sendMessage(multiLang.getLang().get("third"));
}
}
the source code for GroupLang<T>
for reference
public interface GroupLang<T extends GroupLangConfiguration> {
Optional<T> getByLocale(String locale);
T getDefault();
void fetchById(String locale);
void fetch();
}