Skip to content

Commit 0e6b5fd

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents cc40ab5 + 9db7f62 commit 0e6b5fd

3 files changed

Lines changed: 123 additions & 0 deletions

File tree

build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ dependencies {
6767
implementation('io.ktor:ktor-server-host-common:1.6.8')
6868
implementation('io.ktor:ktor-server-netty:1.6.8')
6969
implementation('io.ktor:ktor-serialization:1.6.8')
70+
//Mixins
71+
implementation 'com.github.ReflxctionDev.Tuna-Bytes:core:1.2.0'
72+
annotationProcessor 'com.github.ReflxctionDev.Tuna-Bytes:core:1.2.0'
7073
//Other
7174
implementation 'com.github.TheSimpleTeam:Spiget:master-SNAPSHOT'
7275
implementation 'com.google.code.gson:gson:2.9.0'
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2022 minemobs
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package io.tunabytes.classloader;
26+
27+
import java.lang.invoke.MethodHandles;
28+
import java.lang.invoke.MethodHandles.Lookup;
29+
import java.lang.reflect.AccessibleObject;
30+
import java.lang.reflect.InvocationTargetException;
31+
import java.lang.reflect.Method;
32+
import java.security.ProtectionDomain;
33+
34+
public final class Java11 implements ClassDefiner {
35+
36+
private final Method defineClass = getDefineClassMethod();
37+
38+
private Method getDefineClassMethod() {
39+
try {
40+
return getDeclaredMethod(ClassLoader.class, "defineClass",
41+
String.class, byte[].class, int.class, int.class, ProtectionDomain.class);
42+
} catch (NoSuchMethodException e) {
43+
throw new RuntimeException("cannot initialize", e);
44+
} catch (ClassNotFoundException | InvocationTargetException | IllegalAccessException e) {
45+
throw new RuntimeException(e);
46+
}
47+
}
48+
49+
private Method getDeclaredMethod(Class<?> clazz, String name, Class<?>... parameterTypes) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
50+
Method getDeclaredMethod = Class.forName("io.tunabytes.classloader.SecurityActions")
51+
.getDeclaredMethod("getDeclaredMethod", Class.class, String.class, Class[].class);
52+
getDeclaredMethod.setAccessible(true);
53+
return (Method) getDeclaredMethod.invoke(null, clazz, name, parameterTypes);
54+
}
55+
56+
@Override
57+
public Class<?> defineClass(String name, byte[] b, int off, int len, Class<?> neighbor,
58+
ClassLoader loader, ProtectionDomain protectionDomain)
59+
throws ClassFormatError {
60+
if (neighbor != null)
61+
return toClass(neighbor, b);
62+
else {
63+
// Lookup#defineClass() is not available. So fallback to invoking defineClass on
64+
// ClassLoader, which causes a warning message.
65+
66+
try {
67+
setAccessible(defineClass, true);
68+
return (Class<?>) defineClass.invoke(loader, new Object[]{
69+
name, b, off, len, protectionDomain
70+
});
71+
} catch (Throwable e) {
72+
sneakyThrow(e);
73+
return null;
74+
}
75+
}
76+
}
77+
78+
private void setAccessible(final AccessibleObject ao, final boolean accessible) throws InvocationTargetException, IllegalAccessException,
79+
ClassNotFoundException, NoSuchMethodException {
80+
Method setAccessible = Class.forName("io.tunabytes.classloader.SecurityActions").getDeclaredMethod("setAccessible", AccessibleObject.class, boolean.class);
81+
setAccessible.setAccessible(true);
82+
setAccessible.invoke(null, ao, accessible);
83+
}
84+
85+
private static RuntimeException sneakyThrow(Throwable t) {
86+
if (t == null) throw new NullPointerException("t");
87+
return sneakyThrow0(t);
88+
}
89+
90+
private static <T extends Throwable> T sneakyThrow0(Throwable t) throws T {
91+
throw (T) t;
92+
}
93+
94+
/**
95+
* Loads a class file by {@code java.lang.invoke.MethodHandles.Lookup}.
96+
* It is obtained by using {@code neighbor}.
97+
*
98+
* @param neighbor a class belonging to the same package that the loaded
99+
* class belogns to.
100+
* @param bcode the bytecode.
101+
* @since 3.24
102+
*/
103+
public static Class<?> toClass(Class<?> neighbor, byte[] bcode) {
104+
try {
105+
TunaClassDefiner.class.getModule().addReads(neighbor.getModule());
106+
Lookup lookup = MethodHandles.lookup();
107+
Lookup prvlookup = MethodHandles.privateLookupIn(neighbor, lookup);
108+
return prvlookup.defineClass(bcode);
109+
} catch (IllegalAccessException | IllegalArgumentException e) {
110+
throw new IllegalArgumentException(e.getMessage() + ": " + neighbor.getName()
111+
+ " has no permission to define the class");
112+
}
113+
}
114+
115+
@Override public boolean requiresNeighbor() {
116+
return true;
117+
}
118+
}

src/main/java/net/thesimpleteam/simplebot/SimpleBot.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.jagrosh.jdautilities.command.CommandEvent;
1010
import com.jagrosh.jdautilities.commons.waiter.EventWaiter;
1111
import fr.simpleteam.simplebot.api.Server;
12+
import io.tunabytes.bytecode.MixinsBootstrap;
1213
import net.dv8tion.jda.api.JDA;
1314
import net.dv8tion.jda.api.JDABuilder;
1415
import net.dv8tion.jda.api.OnlineStatus;
@@ -72,6 +73,7 @@ private record Bot(List<Command> commands, String ownerID, String serverInvite)
7273
public static void main(String[] args) throws InterruptedException {
7374
System.out.println("Is in dev mode :" + isInDevMode());
7475
executorService = Executors.newScheduledThreadPool(3);
76+
MixinsBootstrap.init();
7577
try {
7678
String arg = "";
7779
try {

0 commit comments

Comments
 (0)