/
BookLoader.java
196 lines (167 loc) · 8.2 KB
/
BookLoader.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
package slimeknights.mantle.client.book;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.IReloadableResourceManager;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.HashMap;
import javax.annotation.Nonnull;
import slimeknights.mantle.Mantle;
import slimeknights.mantle.client.book.action.StringActionProcessor;
import slimeknights.mantle.client.book.action.protocol.ProtocolGoToPage;
import slimeknights.mantle.client.book.data.BookData;
import slimeknights.mantle.client.book.data.PageData;
import slimeknights.mantle.client.book.data.SectionData;
import slimeknights.mantle.client.book.data.content.ContentBlank;
import slimeknights.mantle.client.book.data.content.ContentBlockInteraction;
import slimeknights.mantle.client.book.data.content.ContentCrafting;
import slimeknights.mantle.client.book.data.content.ContentError;
import slimeknights.mantle.client.book.data.content.ContentImage;
import slimeknights.mantle.client.book.data.content.ContentImageText;
import slimeknights.mantle.client.book.data.content.ContentSmelting;
import slimeknights.mantle.client.book.data.content.ContentSmithing;
import slimeknights.mantle.client.book.data.content.ContentStructure;
import slimeknights.mantle.client.book.data.content.ContentText;
import slimeknights.mantle.client.book.data.content.ContentTextImage;
import slimeknights.mantle.client.book.data.content.ContentTextLeftImage;
import slimeknights.mantle.client.book.data.content.ContentTextRightImage;
import slimeknights.mantle.client.book.data.content.PageContent;
import slimeknights.mantle.client.book.data.deserializer.HexStringDeserializer;
import slimeknights.mantle.client.book.repository.BookRepository;
import slimeknights.mantle.network.NetworkWrapper;
import slimeknights.mantle.network.book.PacketUpdateSavedPage;
@SideOnly(Side.CLIENT)
public class BookLoader implements IResourceManagerReloadListener {
/** GSON object to be used for book loading purposes */
public static final Gson GSON = new GsonBuilder().registerTypeAdapter(int.class, new HexStringDeserializer())
.create();
/** Maps page content presets to names */
private static final HashMap<String, Class<? extends PageContent>> typeToContentMap = new HashMap<>();
/** Internal registry of all books for the purposes of the reloader, maps books to name */
private static final HashMap<String, BookData> books = new HashMap<>();
private static final NetworkWrapper wrapper = new NetworkWrapper("mantle:books");
public BookLoader() {
((IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager()).registerReloadListener(this);
wrapper.registerPacketServer(PacketUpdateSavedPage.class);
// Register page types
registerPageType("blank", ContentBlank.class);
registerPageType("text", ContentText.class);
registerPageType("image", ContentImage.class);
registerPageType("image with text below", ContentImageText.class);
registerPageType("text with image below", ContentTextImage.class);
registerPageType("text with left image etch", ContentTextLeftImage.class);
registerPageType("text with right image etch", ContentTextRightImage.class);
registerPageType("crafting", ContentCrafting.class);
registerPageType("smelting", ContentSmelting.class);
registerPageType("smithing", ContentSmithing.class);
registerPageType("block interaction", ContentBlockInteraction.class);
registerPageType("structure", ContentStructure.class);
// Register action protocols
StringActionProcessor.registerProtocol(new ProtocolGoToPage());
StringActionProcessor.registerProtocol(new ProtocolGoToPage(true, ProtocolGoToPage.GO_TO_RTN));
}
/**
* Registers a type of page prefabricate
*
* @param name The name of the page type
* @param clazz The PageContent class for this page type
* @RecommendedInvoke init
*/
public static void registerPageType(String name, Class<? extends PageContent> clazz) {
if(typeToContentMap.containsKey(name)) {
throw new IllegalArgumentException("Page type " + name + " already in use.");
}
typeToContentMap.put(name, clazz);
}
/**
* Gets a type of page prefabricate by name
*
* @param name The name of the page type
* @return The class of the page type, ContentError.class if page type not registered
*/
public static Class<? extends PageContent> getPageType(String name) {
return typeToContentMap.get(name);
}
/**
* Adds a book to the loader, and returns a reference object
* Be warned that the returned BookData object is not immediately populated, and is instead populated when the resources are loaded/reloaded
*
* @param name The name of the book, modid: will be automatically appended to the front of the name unless that is already added
* @param repositories All the repositories the book will load the sections from
* @return The book object, not immediately populated
*/
public static BookData registerBook(String name, BookRepository... repositories) {
return registerBook(name, true, true, repositories);
}
/**
* Adds a book to the loader, and returns a reference object
* Be warned that the returned BookData object is not immediately populated, and is instead populated when the resources are loaded/reloaded
*
* @param name The name of the book, modid: will be automatically appended to the front of the name unless that is already added
* @param appendIndex Whether an index should be added to the front of the book using a BookTransformer
* @param appendContentTable Whether a table of contents should be added to the front of each section using a BookTransformer
* @param repositories All the repositories the book will load the sections from
* @return The book object, not immediately populated
*/
public static BookData registerBook(String name, boolean appendIndex, boolean appendContentTable, BookRepository... repositories) {
BookData info = new BookData(repositories);
books.put(name.contains(":") ? name : Loader.instance().activeModContainer().getModId() + ":" + name, info);
if(appendIndex) {
info.addTransformer(BookTransformer.IndexTranformer());
}
if(appendContentTable) {
info.addTransformer(BookTransformer.contentTableTransformer());
}
return info;
}
/**
* Returns a book by its name
*
* @param name The name of the book, prefixed with modid:
* @return The instance of the book data, or null if the book is not registered
*/
public static BookData getBook(String name) {
return null;
}
public static void updateSavedPage(EntityPlayer player, ItemStack item, String page) {
if(player == null) {
return;
}
if(player.getHeldItem(EnumHand.MAIN_HAND) == null) {
return;
}
BookHelper.writeSavedPage(item, page);
wrapper.network.sendToServer(new PacketUpdateSavedPage(page));
}
/**
* Reloads all the books, called when the resource manager reloads, such as when the resource pack or the language is changed
*/
@Override
public void onResourceManagerReload(@Nonnull IResourceManager resourceManager) {
Mantle.logger.info("Started loading books...");
long time = System.nanoTime();
for(BookData book : books.values()) {
try {
book.load();
} catch(Exception e) {
book.sections.clear();
SectionData section = new SectionData(true);
section.name = "errorenous";
PageData page = new PageData(true);
page.name = "errorenous";
page.content = new ContentError("Failed to load the book due to an unexpected error.", e);
section.pages.add(page);
book.sections.add(section);
e.printStackTrace();
}
}
Mantle.logger.info("Book loading completed in " + ((System.nanoTime() - time) / 1000000000D) + " seconds.");
}
}