- Версия(и) Minecraft
- Скорее всего любая
Часто бывают задачи когда надо что-то сохранить, да вот в мире через world save нельзя / не получается / неэффективно. Тогда можно сохранять своё добро на сервер, почему бы и нет? И редактировать можно вручную, и данные видно, да и удобно довольно, всё таки не везде Map сохранить можно. С помощью этого кода можно реализовать сохранение каких-либо уровней игрока, XP, вплоть до списка его друзей. У этой реализации лишь один минус: не такое быстрое исполнение. Но каждый девелапир выбирает сам, так что готов представить сохранение Map'ов на сервер!
Как же ей пользоваться? Да банально просто, допустим, задача такова: сохранять HashMap парами ник игрока : его монеты. Понадобится в CommonProxy (либо главном классе если у вас нет прокси) написать такой код:
Разберём аргументы. "playerMoneys" - название файла без .txt, playerMoneys - наша "таблица" с данными.
Всё предельно просто, но что если нам надо сохранять в файл данные, когда, например игрок делает какое-то действие? Тут тоже довольно просто, достаточно отправлять пакет Client->Server и на сервере уже обрабатывать его. Как сделать чтоб игрок мог получить монеты другого игрока? Есть несколько вариантов: самый простой и ненадёжный - скидывать игроку весь HashMap через сплиты и циклы, когда он входит в игру. Либо пакетиками получать отдельно игроков которые нужны нам. Моё супер-костыльное решение этой проблемы было такое: (не смейтесь пожалуйста слишком громко) отправлять от имени игрока всем сообщение с его монетами а потом удалять на других клиентах и записывать XD. Как ни странно я не жалуюсь на этот метод. Вернёмся к Map'ам. Что же за _SI у меня в конце методов? _II, _SB и т.д.? Это обозначения данных в Map'е (нет, не хотел я просто делать toString для object мапа). Есть всего 4 типа: SI - String Integer = строка и число. SS - String String = строка и строка. II - логично, Integer Integer - число и число. SB - String Boolean - строчка и булиана (да / нет = true / false).
Код:
package mcmodding;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ServerSave {
private static File toSave;
public static FileWriter toSave_w;
public static FileReader toSave_r;
public static BufferedReader toSave_br;
public static Map<String, Integer> loadMap_SI(String fName){
Map<String, Integer> toReturn = new HashMap<String, Integer>();
try {
toSave = new File(fName + ".txt");
if(!toSave.exists()) {
return toReturn;
}
toSave_r = new FileReader(toSave);
toSave_w = new FileWriter(toSave);
toSave_br = new BufferedReader(toSave_r);
String line = toSave_br.readLine();
while(line != null) {
String[] a = line.split(":");
if(a.length > 2 || a.length == 1 || a.length == 0) {
line = toSave_br.readLine();
continue;
}
String str = a[0];
int integer = Integer.valueOf(a[1]);
toReturn.put(str, integer);
line = toSave_br.readLine();
}
} catch(IOException e) {
e.printStackTrace();
}
return toReturn;
}
public static Map<String, String> loadMap_SS(String fName){
Map<String, String> toReturn = new HashMap<String, String>();
try {
toSave = new File(fName + ".txt");
if(!toSave.exists()) {
return toReturn;
}
toSave_r = new FileReader(toSave);
toSave_w = new FileWriter(toSave);
toSave_br = new BufferedReader(toSave_r);
String line = toSave_br.readLine();
while(line != null) {
String[] a = line.split(":");
if(a.length > 2 || a.length == 1 || a.length == 0) {
line = toSave_br.readLine();
continue;
}
String str1 = a[0];
String str2 = a[1];
toReturn.put(str1, str2);
line = toSave_br.readLine();
}
} catch(IOException e) {
e.printStackTrace();
}
return toReturn;
}
public static Map<Integer, Integer> loadMap_II(String fName){
Map<Integer, Integer> toReturn = new HashMap<Integer, Integer>();
try {
toSave = new File(fName + ".txt");
if(!toSave.exists()) {
return toReturn;
}
toSave_r = new FileReader(toSave);
toSave_w = new FileWriter(toSave);
toSave_br = new BufferedReader(toSave_r);
String line = toSave_br.readLine();
while(line != null) {
String[] a = line.split(":");
if(a.length > 2 || a.length == 1 || a.length == 0) {
line = toSave_br.readLine();
continue;
}
int int1 = Integer.valueOf(a[0]);
int int2 = Integer.valueOf(a[1]);
toReturn.put(int1, int2);
line = toSave_br.readLine();
}
toSave_br.close();
} catch(IOException e) {
e.printStackTrace();
}
return toReturn;
}
public static Map<String, Boolean> loadMap_SB(String fName){
Map<String, Boolean> toReturn = new HashMap<String, Boolean>();
try {
toSave = new File(fName + ".txt");
if(!toSave.exists()) {
return toReturn;
}
toSave_r = new FileReader(toSave);
toSave_w = new FileWriter(toSave);
toSave_br = new BufferedReader(toSave_r);
String line = toSave_br.readLine();
while(line != null) {
String[] a = line.split(":");
if(a.length > 2 || a.length == 1 || a.length == 0) {
line = toSave_br.readLine();
continue;
}
String str = a[0];
boolean bool = Boolean.valueOf(a[1]);
toReturn.put(str, bool);
line = toSave_br.readLine();
}
toSave_br.close();
} catch(IOException e) {
e.printStackTrace();
}
return toReturn;
}
public static void saveMap_SI(Map<String, Integer> map, String fName) {
if(map != null) {
List<String> strings = new ArrayList<String>(map.keySet());
List<Integer> integers = new ArrayList<Integer>(map.values());
try {
toSave = new File(fName + ".txt");
FileWriter toSave_d = new FileWriter(toSave, false);
toSave_d.write("");
toSave_d.close();
toSave_w = new FileWriter(toSave, true);
BufferedWriter toSave_bw = new BufferedWriter(toSave_w);
for(int i = 0; i < strings.size(); i++) {
String str = strings.get(i);
Integer integer = integers.get(i);
String toWrite = str + ":" + integer + "\n";
toSave_bw.write(toWrite);
}
toSave_bw.close();
} catch(IOException e) {e.printStackTrace();}
}
}
public static void saveMap_SS(Map<String, String> map, String fName) {
if(map != null) {
List<String> strings1 = new ArrayList<String>(map.keySet());
List<String> strings2 = new ArrayList<String>(map.values());
try {
toSave = new File(fName + ".txt");
FileWriter toSave_d = new FileWriter(toSave, false);
toSave_d.write("");
toSave_d.close();
toSave_w = new FileWriter(toSave, true);
BufferedWriter toSave_bw = new BufferedWriter(toSave_w);
for(int i = 0; i < strings1.size(); i++) {
String str1 = strings1.get(i);
String str2 = strings2.get(i);
String toWrite = str1 + ":" + str2 + "\n";
toSave_bw.write(toWrite);
}
toSave_bw.close();
} catch(IOException e) {e.printStackTrace();}
}
}
public static void saveMap_II(Map<Integer, Integer> map, String fName) {
if(map != null) {
List<Integer> ints1 = new ArrayList<Integer>(map.keySet());
List<Integer> ints2 = new ArrayList<Integer>(map.values());
try {
toSave = new File(fName + ".txt");
FileWriter toSave_d = new FileWriter(toSave, false);
toSave_d.write("");
toSave_d.close();
toSave_w = new FileWriter(toSave, true);
BufferedWriter toSave_bw = new BufferedWriter(toSave_w);
for(int i = 0; i < ints1.size(); i++) {
int int1 = ints1.get(i);
int int2 = ints2.get(i);
String toWrite = int1 + ":" + int2 + "\n";
toSave_bw.write(toWrite);
}
toSave_bw.close();
} catch(IOException e) {e.printStackTrace();}
}
}
public static void saveMap_SB(Map<String, Boolean> map, String fName) {
if(map != null) {
List<String> strings = new ArrayList<String>(map.keySet());
List<Boolean> booleans = new ArrayList<Boolean>(map.values());
try {
toSave = new File(fName + ".txt");
FileWriter toSave_d = new FileWriter(toSave, false);
toSave_d.write("");
toSave_d.close();
toSave_w = new FileWriter(toSave, true);
BufferedWriter toSave_bw = new BufferedWriter(toSave_w);
for(int i = 0; i < strings.size(); i++) {
String str = strings.get(i);
boolean bool = booleans.get(i);
String toWrite = str + ":" + bool + "\n";
toSave_bw.write(toWrite);
}
toSave_bw.close();
} catch(IOException e) {e.printStackTrace();}
}
}
}
Код:
public static Map<String, Integer> playerMoneys = new HashMap<String, Integer>();
// выше мы создаём этот мап и можем позже использовать другими классами
@EventHandler
public void serverStarting(FMLServerStartingEvent e) { // эвент старта сервера
playerMoneys = ServerSave.loadMap_SI("playerMoneys"); // .txt автоматически добавляется
}
// а тут будем сохранять его после использования другими классами
@EventHandler
public void serverStopping(FMLServerStoppingEvent e) { // эвент стопа сервера
ServerSave.saveMap_SI(playerMoneys, "playerMoneys");
// если неправильно указать название файла, оно не сохранится!!
}
Всё предельно просто, но что если нам надо сохранять в файл данные, когда, например игрок делает какое-то действие? Тут тоже довольно просто, достаточно отправлять пакет Client->Server и на сервере уже обрабатывать его. Как сделать чтоб игрок мог получить монеты другого игрока? Есть несколько вариантов: самый простой и ненадёжный - скидывать игроку весь HashMap через сплиты и циклы, когда он входит в игру. Либо пакетиками получать отдельно игроков которые нужны нам. Моё супер-костыльное решение этой проблемы было такое: (не смейтесь пожалуйста слишком громко) отправлять от имени игрока всем сообщение с его монетами а потом удалять на других клиентах и записывать XD. Как ни странно я не жалуюсь на этот метод. Вернёмся к Map'ам. Что же за _SI у меня в конце методов? _II, _SB и т.д.? Это обозначения данных в Map'е (нет, не хотел я просто делать toString для object мапа). Есть всего 4 типа: SI - String Integer = строка и число. SS - String String = строка и строка. II - логично, Integer Integer - число и число. SB - String Boolean - строчка и булиана (да / нет = true / false).