Skip to content

Commit bb098e3

Browse files
authored
Add files via upload
1 parent dd7c91c commit bb098e3

File tree

21 files changed

+883
-0
lines changed

21 files changed

+883
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package org.abstruck.qwq;
2+
3+
import net.fabricmc.api.ModInitializer;
4+
import org.abstruck.qwq.library.event.reflection.EventLoader;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
8+
/**
9+
* @author Goulixiaoji
10+
*/
11+
public class QwQ implements ModInitializer {
12+
public static final String MOD_ID = "qwq";
13+
public static final Logger LOGGER = LoggerFactory.getLogger(QwQ.class);
14+
15+
@Override
16+
public void onInitialize() {
17+
LOGGER.info("[QωQ] Who stole my strawberry cake!");
18+
EventLoader.initEvent("std.init.event");
19+
}
20+
}
21+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.abstruck.qwq.client;
2+
3+
import net.fabricmc.api.ClientModInitializer;
4+
import net.fabricmc.api.Environment;
5+
import net.fabricmc.api.EnvType;
6+
7+
/**
8+
* @author Goulixiaoji
9+
*/
10+
@Environment(EnvType.CLIENT)
11+
public class QwQClient implements ClientModInitializer {
12+
13+
@Override
14+
public void onInitializeClient() {
15+
16+
}
17+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.abstruck.qwq.library.event;
2+
3+
import net.fabricmc.api.EnvType;
4+
5+
import java.lang.annotation.ElementType;
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.RetentionPolicy;
8+
import java.lang.annotation.Target;
9+
10+
/**
11+
* @author Goulixiaoji
12+
*/
13+
@Target(ElementType.TYPE)
14+
@Retention(RetentionPolicy.RUNTIME)
15+
public @interface ModEvent {
16+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.abstruck.qwq.library.event;
2+
3+
import net.fabricmc.api.EnvType;
4+
5+
import java.lang.annotation.ElementType;
6+
import java.lang.annotation.Retention;
7+
import java.lang.annotation.RetentionPolicy;
8+
import java.lang.annotation.Target;
9+
10+
/**
11+
* @author Goulixiaoji
12+
*/
13+
14+
@Target(ElementType.METHOD)
15+
@Retention(RetentionPolicy.RUNTIME)
16+
public @interface SubscribeEvent {
17+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.abstruck.qwq.library.event.reflection;
2+
3+
import java.lang.reflect.Method;
4+
import java.util.ArrayList;
5+
import java.util.HashMap;
6+
import java.util.List;
7+
import java.util.Map;
8+
9+
/**
10+
* @author Goulixiaoji
11+
*/
12+
public class EventHandle {
13+
protected static final List<MethodWithClass> EVENT_METHODS = new ArrayList<>();
14+
protected static final Map<String, Boolean> EVENT_PATHS = new HashMap<>();
15+
16+
protected static class MethodWithClass{
17+
private Class<?> klass;
18+
private Method method;
19+
public MethodWithClass(Class<?> klass, Method method){
20+
this.klass = klass;
21+
this.method = method;
22+
}
23+
24+
public Class<?> getKlass() {
25+
return klass;
26+
}
27+
28+
public Method getMethod() {
29+
return method;
30+
}
31+
}
32+
}
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
package org.abstruck.qwq.library.event.reflection;
2+
3+
import net.fabricmc.api.EnvType;
4+
import org.abstruck.qwq.QwQ;
5+
import org.abstruck.qwq.library.event.ModEvent;
6+
import org.abstruck.qwq.library.event.SubscribeEvent;
7+
8+
import java.io.File;
9+
import java.io.IOException;
10+
import java.lang.annotation.Annotation;
11+
import java.lang.reflect.Method;
12+
import java.net.JarURLConnection;
13+
import java.net.URL;
14+
import java.util.*;
15+
import java.util.jar.JarEntry;
16+
17+
/**
18+
* @author Goulixiaoji
19+
*/
20+
public class EventLoader extends EventHandle{
21+
private static final String FILE = "file";
22+
private static final String JAR = "jar";
23+
private static final String DOT_CLASS = ".class";
24+
25+
public static void initEvent(String eventPath){
26+
EventLoader.initEvent(eventPath, true);
27+
}
28+
29+
public static void initEvent(String eventPath, Boolean enable){
30+
eventPath = eventPath.replace(".", "/");
31+
if (EVENT_PATHS.containsKey(eventPath)){
32+
QwQ.LOGGER.warn("[EventLoader] You have given the same eventPath: " + eventPath);
33+
return;
34+
}
35+
EVENT_PATHS.put(eventPath, enable);
36+
37+
try {
38+
Enumeration<URL> dirs = Thread.currentThread().getContextClassLoader().getResources(eventPath);
39+
while (dirs.hasMoreElements()) {
40+
URL url = dirs.nextElement();
41+
if (url.getProtocol().equals(FILE)) {
42+
List<File> fileList = new ArrayList<>();
43+
EventLoader.listFiles(new File(url.getFile()), fileList);
44+
EventLoader.loadClasses(fileList, eventPath);
45+
}
46+
47+
else if (url.getProtocol().equals(JAR)) {
48+
JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection();
49+
Enumeration<JarEntry> entries = jarURLConnection.getJarFile().entries();
50+
EventLoader.loadJars(entries, eventPath);
51+
}
52+
}
53+
}
54+
catch (IOException | ClassNotFoundException e) {
55+
QwQ.LOGGER.error(e.getMessage());
56+
}
57+
}
58+
59+
public static void reloadEvent(){
60+
for (Iterator<MethodWithClass> method = EVENT_METHODS.iterator(); method.hasNext(); ){
61+
method.remove();
62+
}
63+
64+
for (Map.Entry<String, Boolean> paths : EVENT_PATHS.entrySet()){
65+
if (paths.getValue()){
66+
EventLoader.initEvent(paths.getKey());
67+
}
68+
}
69+
}
70+
71+
public static void enableOrDisableEvent(String eventPath, Boolean isEnable){
72+
if (!EVENT_PATHS.containsKey(eventPath)){
73+
QwQ.LOGGER.error("[EventLoader] " + eventPath + " does not contain!");
74+
return;
75+
}
76+
EVENT_PATHS.put(eventPath, isEnable);
77+
}
78+
79+
private static void listFiles(File dir, List<File> fileList){
80+
if (dir.isDirectory()) {
81+
for (File file : dir.listFiles()) {
82+
EventLoader.listFiles(file, fileList);
83+
}
84+
} else {
85+
if (dir.getName().endsWith(DOT_CLASS)) {
86+
fileList.add(dir);
87+
}
88+
}
89+
}
90+
91+
private static void loadJars(Enumeration<JarEntry> entries, String path) throws ClassNotFoundException {
92+
while (entries.hasMoreElements()) {
93+
JarEntry entry = entries.nextElement();
94+
if(entry.getName().endsWith(DOT_CLASS)) {
95+
// \\ -> /
96+
String filePath = entry.getName().replaceAll("\\\\","/") ;
97+
if (filePath.indexOf(path) != 0){
98+
continue;
99+
}
100+
filePath = filePath.replace(DOT_CLASS,"").replaceAll("/", ".");
101+
102+
EventLoader.checkClass(filePath);
103+
}
104+
}
105+
}
106+
107+
private static void loadClasses(List<File> classes, String path) throws ClassNotFoundException {
108+
for (File file : classes){
109+
// \\ -> /
110+
String filePath = file.getAbsolutePath().replaceAll("\\\\","/");
111+
String packageName = filePath.substring(filePath.lastIndexOf(path));
112+
packageName = packageName.replace(DOT_CLASS,"").replaceAll("/", ".");
113+
114+
EventLoader.checkClass(packageName);
115+
}
116+
}
117+
118+
private static void checkClass(String packageName) throws ClassNotFoundException {
119+
Class<?> klass = Class.forName(packageName);
120+
if (null != klass.getAnnotation(ModEvent.class)){
121+
EventLoader.loadMethods(klass);
122+
}
123+
}
124+
125+
private static void loadMethods(Class<?> klass){
126+
Method[] methods = klass.getDeclaredMethods();
127+
for (Method method : methods){
128+
if (null != method.getAnnotation(SubscribeEvent.class)){
129+
130+
Class<?>[] parameter = method.getParameterTypes();
131+
if (parameter.length != 1) {
132+
QwQ.LOGGER.error("[EventLoader] " + klass.getName() + "::" + method.getName() + " can only have one parameter type.");
133+
continue;
134+
}
135+
QwQ.LOGGER.info("[EventLoader] Have been Subscribing Event: " + klass.getName() + "::" + method.getName() + "(" + parameter[0].getName() + ")");
136+
137+
EVENT_METHODS.add(new MethodWithClass(klass, method));
138+
}
139+
}
140+
}
141+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.abstruck.qwq.library.event.reflection;
2+
3+
import org.abstruck.qwq.QwQ;
4+
import org.abstruck.qwq.library.events.IEvent;
5+
6+
import java.lang.reflect.InvocationTargetException;
7+
import java.lang.reflect.Method;
8+
import java.util.function.Supplier;
9+
10+
/**
11+
* @author Goulixiaoji
12+
*/
13+
public class EventManager extends EventHandle{
14+
15+
public static void onEventAction(Supplier<? extends IEvent> onEvent) {
16+
for (MethodWithClass methodWithClass : EVENT_METHODS){
17+
Method method = methodWithClass.getMethod();
18+
Class<?>[] parameter = method.getParameterTypes();
19+
20+
if (onEvent.get().getClass().equals(parameter[0])){
21+
method.setAccessible(true);
22+
try {
23+
method.invoke(methodWithClass.getKlass(), onEvent.get());
24+
} catch (IllegalAccessException | InvocationTargetException e) {
25+
QwQ.LOGGER.error(e.getMessage());
26+
}
27+
}
28+
}
29+
}
30+
31+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.abstruck.qwq.library.events;
2+
3+
/**
4+
* @author Goulixiaoji
5+
*/
6+
public interface IEvent {
7+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package org.abstruck.qwq.library.events.block;
2+
3+
import net.minecraft.block.BlockState;
4+
import net.minecraft.block.entity.BlockEntity;
5+
import net.minecraft.entity.player.PlayerEntity;
6+
import net.minecraft.item.ItemStack;
7+
import net.minecraft.util.math.BlockPos;
8+
import net.minecraft.world.World;
9+
import net.minecraft.world.WorldAccess;
10+
import org.abstruck.qwq.library.events.IEvent;
11+
import org.jetbrains.annotations.Nullable;
12+
13+
/**
14+
* @author Goulixiaoji
15+
*/
16+
public class BlockEvent implements IEvent {
17+
private BlockState state;
18+
public BlockEvent(BlockState state){
19+
this.state = state;
20+
}
21+
22+
public BlockState getState() {
23+
return state;
24+
}
25+
26+
public static class OnBreakEvent extends BlockEvent{
27+
private World world;
28+
private BlockPos pos;
29+
private PlayerEntity player;
30+
31+
public OnBreakEvent(World world, BlockPos pos, BlockState state, PlayerEntity player){
32+
super(state);
33+
this.world = world;
34+
this.pos = pos;
35+
this.player = player;
36+
}
37+
38+
public World getWorld() {
39+
return world;
40+
}
41+
42+
public BlockPos getPos() {
43+
return pos;
44+
}
45+
46+
public PlayerEntity getPlayer() {
47+
return player;
48+
}
49+
}
50+
51+
public static class OnBrokenEvent extends BlockEvent{
52+
private WorldAccess world;
53+
private BlockPos pos;
54+
public OnBrokenEvent(WorldAccess world, BlockPos pos, BlockState state) {
55+
super(state);
56+
this.world = world;
57+
this.pos = pos;
58+
}
59+
60+
public WorldAccess getWorld() {
61+
return world;
62+
}
63+
64+
public BlockPos getPos() {
65+
return pos;
66+
}
67+
}
68+
69+
public static class AfterBreakEvent extends BlockEvent{
70+
private World world;
71+
private PlayerEntity player;
72+
private BlockPos pos;
73+
private BlockEntity blockEntity;
74+
private ItemStack stack;
75+
public AfterBreakEvent(World world, PlayerEntity player, BlockPos pos, BlockState state, @Nullable BlockEntity blockEntity, ItemStack stack) {
76+
super(state);
77+
this.world = world;
78+
this.player = player;
79+
this.pos = pos;
80+
this.blockEntity = blockEntity;
81+
this.stack = stack;
82+
}
83+
84+
public PlayerEntity getPlayer() {
85+
return player;
86+
}
87+
88+
public BlockPos getPos() {
89+
return pos;
90+
}
91+
92+
public World getWorld() {
93+
return world;
94+
}
95+
96+
public BlockEntity getBlockEntity() {
97+
return blockEntity;
98+
}
99+
100+
public ItemStack getStack() {
101+
return stack;
102+
}
103+
}
104+
}

0 commit comments

Comments
 (0)