forked from PaperMC/Paperclip
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3136423
commit 28c3ac4
Showing
8 changed files
with
1,051 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
java21/src/main/java/launchwrapper/IClassNameTransformer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/* | ||
* This file is part of project Orion, licensed under the MIT License (MIT). | ||
* | ||
* Copyright (c) Original contributors ("I don't care" license? See https://github.com/Mojang/LegacyLauncher/issues/1) | ||
* Copyright (c) 2017-2018 Mark Vainomaa <[email protected]> | ||
* Copyright (c) Contributors | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
* THE SOFTWARE. | ||
*/ | ||
|
||
package launchwrapper; | ||
|
||
import org.jetbrains.annotations.NotNull; | ||
|
||
|
||
/** | ||
* Class name transformer, useful for mostly obfuscated <-> mapped names | ||
*/ | ||
public interface IClassNameTransformer { | ||
/** | ||
* Remap class name to mapped name | ||
* | ||
* @param name Unmapped class name | ||
* @return Remapped class name; or supplied class name if mapping was not found | ||
*/ | ||
@NotNull | ||
String remapClassName(@NotNull String name); | ||
|
||
/** | ||
* Unmap class name from remapped name | ||
* | ||
* @param name Mapped class name | ||
* @return Unmapped (original) class name; or supplied class name if mapping was not found | ||
*/ | ||
@NotNull | ||
String unmapClassName(@NotNull String name); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
* This file is part of project Orion, licensed under the MIT License (MIT). | ||
* | ||
* Copyright (c) Original contributors ("I don't care" license? See https://github.com/Mojang/LegacyLauncher/issues/1) | ||
* Copyright (c) 2017-2018 Mark Vainomaa <[email protected]> | ||
* Copyright (c) Contributors | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
* THE SOFTWARE. | ||
*/ | ||
|
||
package launchwrapper; | ||
|
||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
|
||
/** | ||
* Class transformer interface | ||
*/ | ||
public interface IClassTransformer { | ||
/** | ||
* Transforms class | ||
* | ||
* Note that class names are using dots instead of slashes. | ||
* | ||
* @param name Class unmapped name | ||
* @param transformedName Class mapped name, may equal to unmapped name | ||
* @param classData Raw class data or null | ||
* @return Transformed (or supplied) class data or null | ||
*/ | ||
@Nullable | ||
byte[] transform(@NotNull String name, @NotNull String transformedName, @Nullable byte[] classData); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
/* | ||
* This file is part of project Orion, licensed under the MIT License (MIT). | ||
* | ||
* Copyright (c) Original contributors ("I don't care" license? See https://github.com/Mojang/LegacyLauncher/issues/1) | ||
* Copyright (c) 2017-2018 Mark Vainomaa <[email protected]> | ||
* Copyright (c) Contributors | ||
* | ||
* Permission is hereby granted, free of charge, to any person obtaining a copy | ||
* of this software and associated documentation files (the "Software"), to deal | ||
* in the Software without restriction, including without limitation the rights | ||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
* copies of the Software, and to permit persons to whom the Software is | ||
* furnished to do so, subject to the following conditions: | ||
* | ||
* The above copyright notice and this permission notice shall be included in | ||
* all copies or substantial portions of the Software. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
* THE SOFTWARE. | ||
*/ | ||
|
||
package launchwrapper; | ||
|
||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.io.File; | ||
import java.util.List; | ||
|
||
/** | ||
* A Tweaker | ||
*/ | ||
public interface ITweaker { | ||
/** | ||
* Parses application's parameters (which you'll supply to app on command line) | ||
* | ||
* @param args {@link List} of application's parameters | ||
*/ | ||
default void acceptOptions(@NotNull List<String> args) { | ||
acceptOptions(args, null, null, null); | ||
} | ||
|
||
/** | ||
* Old {@code acceptOptions} method retained for compatibility reasons. | ||
* | ||
* @param args Application's arguments | ||
* @param gameDir unknown | ||
* @param assetsDir unknown | ||
* @param profile unknown | ||
* @deprecated This method is not used internally. See {@link ITweaker#acceptOptions(List)} | ||
*/ | ||
@Deprecated | ||
default void acceptOptions(@NotNull List<String> args, File gameDir, final File assetsDir, String profile) { | ||
throw new IllegalStateException("Please implement this method."); | ||
} | ||
|
||
/** | ||
* Asks tweaker for transformers and other options | ||
* | ||
* @param classLoader Current {@link LaunchClassLoader} instance | ||
*/ | ||
void injectIntoClassLoader(@NotNull LaunchClassLoader classLoader); | ||
|
||
/** | ||
* Gets arguments which will be added to endpoint's {@code main(String[])} | ||
* | ||
* @return String array of arguments | ||
*/ | ||
@NotNull | ||
String[] getLaunchArguments(); | ||
|
||
/** | ||
* Gets main endpoint class to pass arguments to and start the wrapped application. Only used | ||
* for main tweaker. | ||
* | ||
* @return Endpoint class name | ||
*/ | ||
@NotNull | ||
String getLaunchTarget(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
package launchwrapper; | ||
|
||
import joptsimple.OptionParser; | ||
import joptsimple.OptionSet; | ||
import joptsimple.OptionSpec; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.spongepowered.asm.mixin.MixinEnvironment; | ||
import org.spongepowered.asm.mixin.MixinEnvironment.Side; | ||
import org.spongepowered.asm.mixin.Mixins; | ||
|
||
import java.io.File; | ||
import java.lang.reflect.Method; | ||
import java.net.MalformedURLException; | ||
import java.net.URL; | ||
import java.net.URLClassLoader; | ||
import java.util.*; | ||
|
||
public class Launch { | ||
private static final Logger logger = LoggerFactory.getLogger("LaunchWrapper"); | ||
private static final String DEFAULT_TWEAK = "org.spongepowered.asm.launch.MixinTweaker"; | ||
public static LaunchClassLoader classLoader; | ||
public static Map<String, Object> blackboard = new HashMap<>(); | ||
|
||
Launch(URL[] urls, ClassLoader parent) { | ||
classLoader = new LaunchClassLoader(urls, parent); | ||
Thread.currentThread().setContextClassLoader(classLoader); | ||
} | ||
|
||
private void configureMixin() { | ||
MixinEnvironment.getDefaultEnvironment().setSide(Side.SERVER); | ||
Mixins.addConfiguration("mixins.akarin.core.json"); | ||
} | ||
|
||
private URL[] getURLs() { | ||
String cp = System.getProperty("java.class.path"); | ||
String[] elements = cp.split(File.pathSeparator); | ||
if (elements.length == 0) { | ||
elements = new String[]{""}; | ||
} | ||
URL[] urls = new URL[elements.length]; | ||
for (int i = 0; i < elements.length; i++) { | ||
try { | ||
URL url = new File(elements[i]).toURI().toURL(); | ||
urls[i] = url; | ||
} catch (MalformedURLException ignore) { | ||
// malformed file string or class path element does not exist | ||
} | ||
} | ||
return urls; | ||
} | ||
|
||
private void launch(String[] args) { | ||
final OptionParser parser = new OptionParser(); | ||
parser.allowsUnrecognizedOptions(); | ||
|
||
final OptionSpec<String> tweakClassOption = parser | ||
.accepts("tweakClass", "Tweak class(es) to load") | ||
.withRequiredArg() | ||
.defaultsTo(DEFAULT_TWEAK); | ||
final OptionSpec<String> nonOption = parser.nonOptions(); | ||
|
||
final OptionSet options = parser.parse(args); | ||
final List<String> tweakClassNames = new ArrayList<>(options.valuesOf(tweakClassOption)); | ||
|
||
final List<String> argumentList = new ArrayList<>(); | ||
// This list of names will be interacted with through tweakers. They can append to this list | ||
// any 'discovered' tweakers from their preferred mod loading mechanism | ||
// By making this object discoverable and accessible it's possible to perform | ||
// things like cascading of tweakers | ||
blackboard.put("TweakClasses", tweakClassNames); | ||
|
||
// This argument list will be constructed from all tweakers. It is visible here so | ||
// all tweakers can figure out if a particular argument is present, and add it if not | ||
blackboard.put("ArgumentList", argumentList); | ||
|
||
// This is to prevent duplicates - in case a tweaker decides to add itself or something | ||
final Set<String> visitedTweakerNames = new HashSet<>(); | ||
// The 'definitive' list of tweakers | ||
final List<ITweaker> allTweakers = new ArrayList<>(); | ||
try { | ||
final List<ITweaker> pendingTweakers = new ArrayList<>(tweakClassNames.size() + 1); | ||
// The list of tweak instances - may be useful for interoperability | ||
blackboard.put("Tweaks", pendingTweakers); | ||
// The primary tweaker (the first one specified on the command line) will actually | ||
// be responsible for providing the 'main' name and generally gets called first | ||
ITweaker primaryTweaker = null; | ||
// This loop will terminate, unless there is some sort of pathological tweaker | ||
// that reinserts itself with a new identity every pass | ||
// It is here to allow tweakers to "push" new tweak classes onto the 'stack' of | ||
// tweakers to evaluate allowing for cascaded discovery and injection of tweakers | ||
while (!tweakClassNames.isEmpty()) { | ||
for (final Iterator<String> it = tweakClassNames.iterator(); it.hasNext(); ) { | ||
final String tweakName = it.next(); | ||
// Safety check - don't reprocess something we've already visited | ||
if (visitedTweakerNames.contains(tweakName)) { | ||
logger.warn("Tweak class name {} has already been visited -- skipping", tweakName); | ||
// remove the tweaker from the stack otherwise it will create an infinite loop | ||
it.remove(); | ||
continue; | ||
} else { | ||
visitedTweakerNames.add(tweakName); | ||
} | ||
logger.info("Loading tweak class name {}", tweakName); | ||
|
||
// Ensure we allow the tweak class to load with the parent classloader | ||
classLoader.getClassLoaderExclusions().add(tweakName.substring(0, tweakName.lastIndexOf('.'))); | ||
final ITweaker tweaker = (ITweaker) Class.forName(tweakName, true, classLoader) | ||
.getConstructor().newInstance(); | ||
pendingTweakers.add(tweaker); | ||
|
||
// Remove the tweaker from the list of tweaker names we've processed this pass | ||
it.remove(); | ||
// If we haven't visited a tweaker yet, the first will become the 'primary' tweaker | ||
if (primaryTweaker == null) { | ||
logger.info("Using primary tweak class name {}", tweakName); | ||
primaryTweaker = tweaker; | ||
} | ||
} | ||
|
||
// Configure environment to avoid warn | ||
configureMixin(); | ||
|
||
// Now, iterate all the tweakers we just instantiated | ||
while (!pendingTweakers.isEmpty()) { | ||
final ITweaker tweaker = pendingTweakers.remove(0); | ||
logger.info("Calling tweak class {}", tweaker.getClass().getName()); | ||
tweaker.acceptOptions(options.valuesOf(nonOption)); | ||
tweaker.injectIntoClassLoader(classLoader); | ||
allTweakers.add(tweaker); | ||
} | ||
// continue around the loop until there's no tweak classes | ||
} | ||
|
||
// Once we're done, we then ask all the tweakers for their arguments and add them all to the | ||
// master argument list | ||
for (final ITweaker tweaker : allTweakers) { | ||
argumentList.addAll(Arrays.asList(tweaker.getLaunchArguments())); | ||
} | ||
|
||
final String launchTarget = "org.bukkit.craftbukkit.Main"; | ||
final Class<?> clazz = Class.forName(launchTarget, false, classLoader); | ||
final Method mainMethod = clazz.getMethod("main", String[].class); | ||
|
||
logger.info("Launching wrapped Minecraft {{}}", launchTarget); | ||
// Pass original server arguments | ||
argumentList.addAll(Arrays.asList(args)); | ||
mainMethod.invoke(null, (Object) argumentList.toArray(new String[0])); | ||
} catch (Exception e) { | ||
logger.error("Unable to launch", e); | ||
System.exit(1); | ||
} | ||
} | ||
} |
Oops, something went wrong.
28c3ac4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
下次进行这种程度的更改前 记得更改版本号
然后许可证是什么情况 单独拿一个文件放吧