mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2025-02-16 17:44:23 +01:00
Remove the mixin from the skin drop and mark it as experimental.
It's disabled by default.
This commit is contained in:
parent
8fe228ae5a
commit
d031bb1f43
7 changed files with 104 additions and 218 deletions
|
@ -1,7 +0,0 @@
|
||||||
package com.voxelmodpack.hdskins;
|
|
||||||
|
|
||||||
import net.minecraft.client.resources.DefaultResourcePack;
|
|
||||||
|
|
||||||
public interface IMinecraft {
|
|
||||||
DefaultResourcePack getDefaultResourcePack();
|
|
||||||
}
|
|
|
@ -1,128 +1,102 @@
|
||||||
package com.voxelmodpack.hdskins.gui;
|
package com.voxelmodpack.hdskins.gui;
|
||||||
|
|
||||||
import java.awt.Canvas;
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Frame;
|
|
||||||
import java.awt.dnd.DropTarget;
|
|
||||||
import java.awt.dnd.DropTargetListener;
|
|
||||||
import java.awt.event.ComponentAdapter;
|
|
||||||
import java.awt.event.ComponentEvent;
|
|
||||||
import java.awt.event.WindowAdapter;
|
|
||||||
import java.awt.event.WindowEvent;
|
|
||||||
import java.awt.event.WindowStateListener;
|
|
||||||
import java.io.Closeable;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.TooManyListenersException;
|
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
|
||||||
import javax.swing.JFrame;
|
|
||||||
|
|
||||||
import org.lwjgl.LWJGLException;
|
|
||||||
import org.lwjgl.opengl.Display;
|
|
||||||
import org.lwjgl.opengl.DisplayMode;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.voxelmodpack.hdskins.IMinecraft;
|
|
||||||
import com.voxelmodpack.hdskins.Later;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.resources.DefaultResourcePack;
|
import net.minecraft.client.resources.DefaultResourcePack;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import org.lwjgl.LWJGLException;
|
||||||
|
import org.lwjgl.opengl.AWTGLCanvas;
|
||||||
|
import org.lwjgl.opengl.Display;
|
||||||
|
import org.lwjgl.opengl.PixelFormat;
|
||||||
|
|
||||||
public class GLWindow implements Closeable {
|
import java.awt.Canvas;
|
||||||
|
import java.awt.dnd.DnDConstants;
|
||||||
|
import java.awt.dnd.DropTarget;
|
||||||
|
import java.awt.dnd.DropTargetListener;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.TooManyListenersException;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
static GLWindow instance = null;
|
/**
|
||||||
|
* Experimental window to control file drop. It kind of sucks.
|
||||||
|
*
|
||||||
|
* This has to be enabled using the {@code experimentalSkinDrop} config.
|
||||||
|
*/
|
||||||
|
public class GLWindow extends DropTarget {
|
||||||
|
|
||||||
public static GLWindow current() {
|
private static GLWindow instance = null;
|
||||||
if (instance == null) {
|
|
||||||
|
public static void create() {
|
||||||
|
if (instance == null)
|
||||||
instance = new GLWindow();
|
instance = new GLWindow();
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final DropTarget dt;
|
@Nullable
|
||||||
|
public static GLWindow current() {
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
private final JFrame frame;
|
private final JFrame frame;
|
||||||
|
|
||||||
private DropTargetListener saved = null;
|
private DropTargetListener saved = null;
|
||||||
|
|
||||||
|
// What's so special about these numbers? Are they the same on all systems?
|
||||||
private final int frameX = 15;
|
private final int frameX = 15;
|
||||||
private final int frameY = 36;
|
private final int frameY = 36;
|
||||||
|
|
||||||
private final Minecraft mc = Minecraft.getMinecraft();
|
private final Minecraft mc = Minecraft.getMinecraft();
|
||||||
|
|
||||||
private int state = 0;
|
|
||||||
|
|
||||||
private GLWindow() {
|
private GLWindow() {
|
||||||
int x = Display.getX();
|
|
||||||
int y = Display.getY();
|
|
||||||
|
|
||||||
int w = Display.getWidth() + frameX;
|
|
||||||
|
|
||||||
int h = Display.getHeight() + frameY;
|
|
||||||
|
|
||||||
Canvas canvas = new Canvas();
|
|
||||||
|
|
||||||
frame = new JFrame(Display.getTitle());
|
|
||||||
frame.setResizable(Display.isResizable());
|
|
||||||
frame.setLocation(x, y);
|
|
||||||
frame.setSize(w, h);
|
|
||||||
frame.setBackground(Color.BLACK);
|
|
||||||
frame.getContentPane().setLayout(null);
|
|
||||||
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
|
||||||
frame.addWindowListener(new WindowAdapter() {
|
|
||||||
@Override
|
|
||||||
public void windowClosing(WindowEvent windowEvent) {
|
|
||||||
Minecraft.getMinecraft().shutdown();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
frame.addComponentListener(new ComponentAdapter() {
|
|
||||||
@Override
|
|
||||||
public void componentResized(ComponentEvent componentEvent) {
|
|
||||||
canvas.setBounds(0, 0, frame.getWidth() - frameX, frame.getHeight() - frameY);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
frame.addWindowStateListener(new WindowStateListener() {
|
|
||||||
@Override
|
|
||||||
public void windowStateChanged(WindowEvent event) {
|
|
||||||
state = event.getNewState();
|
|
||||||
Later.performLater(1, () -> {
|
|
||||||
canvas.setBounds(0, 0, frame.getWidth() - frameX, frame.getHeight() - frameY);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
setIcons(frame);
|
|
||||||
|
|
||||||
frame.getContentPane().add(canvas);
|
|
||||||
frame.setVisible(true);
|
|
||||||
|
|
||||||
|
setDefaultActions(DnDConstants.ACTION_LINK);
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
int x = Display.getX();
|
||||||
|
int y = Display.getY();
|
||||||
|
|
||||||
|
int w = Display.getWidth() + frameX;
|
||||||
|
|
||||||
|
int h = Display.getHeight() + frameY;
|
||||||
|
|
||||||
|
Canvas canvas = new AWTGLCanvas(new PixelFormat().withDepthBits(24));
|
||||||
|
|
||||||
|
frame = new JFrame(Display.getTitle());
|
||||||
|
frame.setResizable(Display.isResizable());
|
||||||
|
frame.setLocation(x, y);
|
||||||
|
frame.setSize(w, h);
|
||||||
|
|
||||||
|
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||||
|
|
||||||
|
// FIXME: icon is super small on the task bar
|
||||||
|
setIcons(frame);
|
||||||
|
|
||||||
|
frame.add(canvas);
|
||||||
|
frame.setVisible(true);
|
||||||
|
|
||||||
Display.setParent(canvas);
|
Display.setParent(canvas);
|
||||||
|
|
||||||
|
Display.setFullscreen(mc.isFullScreen());
|
||||||
|
|
||||||
} catch (LWJGLException e) {
|
} catch (LWJGLException e) {
|
||||||
e.printStackTrace();
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Display.getWidth() == Display.getDesktopDisplayMode().getWidth()) {
|
|
||||||
frame.setExtendedState(Frame.MAXIMIZED_BOTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
state = frame.getExtendedState();
|
|
||||||
|
|
||||||
if (mc.isFullScreen()) {
|
|
||||||
try {
|
|
||||||
Display.setFullscreen(true);
|
|
||||||
} catch (LWJGLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dt = new DropTarget();
|
|
||||||
canvas.setDropTarget(dt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final void setIcons(JFrame frame) {
|
public void refresh() {
|
||||||
|
// trigger an update
|
||||||
|
frame.setSize(frame.getWidth(), frame.getHeight()+1);
|
||||||
|
frame.setSize(frame.getWidth(), frame.getHeight()-1);
|
||||||
|
// frame.pack();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setIcons(JFrame frame) {
|
||||||
try {
|
try {
|
||||||
DefaultResourcePack pack = ((IMinecraft)mc).getDefaultResourcePack();
|
// This should be using reflection. No need for this.
|
||||||
|
DefaultResourcePack pack = (DefaultResourcePack) mc.getResourcePackRepository().rprDefaultResourcePack;
|
||||||
|
|
||||||
frame.setIconImages(Lists.newArrayList(
|
frame.setIconImages(Lists.newArrayList(
|
||||||
ImageIO.read(pack.getInputStreamAssets(new ResourceLocation("icons/icon_16x16.png"))),
|
ImageIO.read(pack.getInputStreamAssets(new ResourceLocation("icons/icon_16x16.png"))),
|
||||||
|
@ -133,58 +107,18 @@ public class GLWindow implements Closeable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDropTargetListener(DropTargetListener dtl) {
|
void setDropTargetListener(@Nullable DropTargetListener dtl) {
|
||||||
if (saved != null) {
|
if (saved != null) {
|
||||||
dt.removeDropTargetListener(saved);
|
removeDropTargetListener(saved);
|
||||||
}
|
}
|
||||||
if (dtl != null) {
|
if (dtl == null)
|
||||||
|
frame.setDropTarget(null);
|
||||||
|
else {
|
||||||
|
frame.setDropTarget(this);
|
||||||
try {
|
try {
|
||||||
dt.addDropTargetListener(dtl);
|
addDropTargetListener(dtl);
|
||||||
} catch (TooManyListenersException e) { }
|
} catch (TooManyListenersException e) { }
|
||||||
saved = dtl;
|
saved = dtl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void dispose() {
|
|
||||||
if (instance != null) {
|
|
||||||
try {
|
|
||||||
instance.close();
|
|
||||||
} catch (IOException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() throws IOException {
|
|
||||||
mc.addScheduledTask(() -> {
|
|
||||||
try {
|
|
||||||
Display.setParent(null);
|
|
||||||
} catch (LWJGLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (mc.isFullScreen()) {
|
|
||||||
Display.setFullscreen(true);
|
|
||||||
} else {
|
|
||||||
if ((state & JFrame.MAXIMIZED_BOTH) == JFrame.MAXIMIZED_BOTH) {
|
|
||||||
Display.setLocation(0, 0);
|
|
||||||
Display.setDisplayMode(Display.getDesktopDisplayMode());
|
|
||||||
} else {
|
|
||||||
Display.setDisplayMode(new DisplayMode(mc.displayWidth, mc.displayHeight));
|
|
||||||
Display.setLocation(frame.getX(), frame.getY());
|
|
||||||
}
|
|
||||||
Display.setResizable(false);
|
|
||||||
Display.setResizable(true);
|
|
||||||
}
|
|
||||||
} catch (LWJGLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
frame.setVisible(false);
|
|
||||||
frame.dispose();
|
|
||||||
|
|
||||||
instance = null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,6 @@ import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.DoubleBuffer;
|
import java.nio.DoubleBuffer;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
@ -188,12 +187,15 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
|
||||||
this.btnUpload.enabled = false;
|
this.btnUpload.enabled = false;
|
||||||
this.btnBrowse.enabled = !this.mc.isFullScreen();
|
this.btnBrowse.enabled = !this.mc.isFullScreen();
|
||||||
(this.textureType == SKIN ? this.btnModeSkin : this.btnModeElytra).enabled = false;
|
(this.textureType == SKIN ? this.btnModeSkin : this.btnModeElytra).enabled = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enableDnd() {
|
private void enableDnd() {
|
||||||
GLWindow.current().setDropTargetListener((FileDropListener) files -> {
|
GLWindow window = GLWindow.current();
|
||||||
files.stream().findFirst().ifPresent(instance::loadLocalFile);
|
if (window != null)
|
||||||
});
|
window.setDropTargetListener((FileDropListener) files -> {
|
||||||
|
files.stream().findFirst().ifPresent(instance::loadLocalFile);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initPanoramaRenderer() {
|
private void initPanoramaRenderer() {
|
||||||
|
@ -206,6 +208,10 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
|
||||||
localPlayer.releaseTextures();
|
localPlayer.releaseTextures();
|
||||||
remotePlayer.releaseTextures();
|
remotePlayer.releaseTextures();
|
||||||
HDSkinManager.clearSkinCache();
|
HDSkinManager.clearSkinCache();
|
||||||
|
|
||||||
|
GLWindow window = GLWindow.current();
|
||||||
|
if (window != null)
|
||||||
|
window.setDropTargetListener(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onFileOpenDialogClosed(JFileChooser fileDialog, int dialogResult) {
|
private void onFileOpenDialogClosed(JFileChooser fileDialog, int dialogResult) {
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
package com.voxelmodpack.hdskins.mixin;
|
|
||||||
|
|
||||||
import org.lwjgl.LWJGLException;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import com.voxelmodpack.hdskins.IMinecraft;
|
|
||||||
import com.voxelmodpack.hdskins.gui.GLWindow;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.resources.DefaultResourcePack;
|
|
||||||
import net.minecraft.crash.CrashReport;
|
|
||||||
|
|
||||||
@Mixin(Minecraft.class)
|
|
||||||
public abstract class MixinMinecraft implements IMinecraft {
|
|
||||||
|
|
||||||
@Accessor("mcDefaultResourcePack")
|
|
||||||
public abstract DefaultResourcePack getDefaultResourcePack();
|
|
||||||
|
|
||||||
//
|
|
||||||
// Due to how JFrame works the only way to know for sure when the game hash crashed
|
|
||||||
// is to have it call us explicitly.
|
|
||||||
//
|
|
||||||
// ShutdownListener.onShutDown is unlikely to be called as it depends on the
|
|
||||||
// Minecraft.running flag to be unset, which is unlikely to happen if the game crashes.
|
|
||||||
//
|
|
||||||
// Runtime.current().addShutdownHook won't be called it waits for all
|
|
||||||
// non-daemon threads to end, one of which is depending on the JFrame being
|
|
||||||
// disposed to tell it when to end.
|
|
||||||
//
|
|
||||||
// If you're thinking 'hey, what about Minecraft.isCrashed?'
|
|
||||||
// No, that's only set if the internal MinecraftServer crashes.
|
|
||||||
// Otherwise the value is always false and threads spinning to check any such value
|
|
||||||
// will only serve to hang up the VM.
|
|
||||||
//
|
|
||||||
// @forge
|
|
||||||
// Because the minecraft forge team are stupid, they call displayCrashReport on startup
|
|
||||||
// regardless of whether the game has crashed or not. Thus the window may flicker an additional
|
|
||||||
// time as the native window is forced back to the front.
|
|
||||||
// This is a minor issue as the window will simply reassert itself when it's next referenced
|
|
||||||
// (i.e. The skins GUI uses it for file drops) so I have no intention of fixing this.
|
|
||||||
//
|
|
||||||
// This is their problem.
|
|
||||||
//
|
|
||||||
//public void displayCrashReport(CrashReport crashReportIn)
|
|
||||||
@Inject(method = "displayCrashReport(Lnet/minecraft/crash/CrashReport;)V", at = @At("HEAD"))
|
|
||||||
private void onGameCrash(CrashReport report, CallbackInfo info) {
|
|
||||||
GLWindow.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// To avoid flickering as much as possible, create the window as close to Minecraft
|
|
||||||
// creating its native window as possible.
|
|
||||||
//
|
|
||||||
// Litemods are initialised after this, init complete is called later, and forge mods
|
|
||||||
// are called EVEN LATER.
|
|
||||||
//
|
|
||||||
//private void createDisplay() throws LWJGLException
|
|
||||||
@Inject(method = "createDisplay()V", at = @At("RETURN"))
|
|
||||||
private void onCreateDisplay(CallbackInfo info) throws LWJGLException {
|
|
||||||
GLWindow.current();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@ package com.voxelmodpack.hdskins.mod;
|
||||||
|
|
||||||
import com.mumfrey.liteloader.Configurable;
|
import com.mumfrey.liteloader.Configurable;
|
||||||
import com.mumfrey.liteloader.InitCompleteListener;
|
import com.mumfrey.liteloader.InitCompleteListener;
|
||||||
|
import com.mumfrey.liteloader.ViewportListener;
|
||||||
|
|
||||||
public interface HDSkinsMod extends InitCompleteListener, Configurable {
|
public interface HDSkinsMod extends InitCompleteListener, ViewportListener, Configurable {
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,13 @@ import com.mumfrey.liteloader.modconfig.ExposableOptions;
|
||||||
import com.mumfrey.liteloader.util.ModUtilities;
|
import com.mumfrey.liteloader.util.ModUtilities;
|
||||||
import com.voxelmodpack.hdskins.HDSkinManager;
|
import com.voxelmodpack.hdskins.HDSkinManager;
|
||||||
import com.voxelmodpack.hdskins.gui.EntityPlayerModel;
|
import com.voxelmodpack.hdskins.gui.EntityPlayerModel;
|
||||||
|
import com.voxelmodpack.hdskins.gui.GLWindow;
|
||||||
import com.voxelmodpack.hdskins.gui.GuiSkins;
|
import com.voxelmodpack.hdskins.gui.GuiSkins;
|
||||||
import com.voxelmodpack.hdskins.gui.HDSkinsConfigPanel;
|
import com.voxelmodpack.hdskins.gui.HDSkinsConfigPanel;
|
||||||
import com.voxelmodpack.hdskins.gui.RenderPlayerModel;
|
import com.voxelmodpack.hdskins.gui.RenderPlayerModel;
|
||||||
import com.voxelmodpack.hdskins.skins.SkinServer;
|
import com.voxelmodpack.hdskins.skins.SkinServer;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.gui.ScaledResolution;
|
||||||
import net.minecraft.client.resources.IReloadableResourceManager;
|
import net.minecraft.client.resources.IReloadableResourceManager;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -24,6 +26,8 @@ public class LiteModHDSkinsMod implements HDSkinsMod {
|
||||||
|
|
||||||
@Expose
|
@Expose
|
||||||
public List<String> skin_servers = SkinServer.defaultServers;
|
public List<String> skin_servers = SkinServer.defaultServers;
|
||||||
|
@Expose
|
||||||
|
public boolean experimentalSkinDrop = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
@ -54,6 +58,8 @@ public class LiteModHDSkinsMod implements HDSkinsMod {
|
||||||
|
|
||||||
IReloadableResourceManager irrm = (IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager();
|
IReloadableResourceManager irrm = (IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager();
|
||||||
irrm.registerReloadListener(HDSkinManager.INSTANCE);
|
irrm.registerReloadListener(HDSkinManager.INSTANCE);
|
||||||
|
|
||||||
|
if (experimentalSkinDrop) GLWindow.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -78,5 +84,18 @@ public class LiteModHDSkinsMod implements HDSkinsMod {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewportResized(ScaledResolution resolution, int displayWidth, int displayHeight) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFullScreenToggled(boolean fullScreen) {
|
||||||
|
if (!fullScreen && GLWindow.current() != null) {
|
||||||
|
GLWindow.current().refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
"package": "com.voxelmodpack.hdskins.mixin",
|
"package": "com.voxelmodpack.hdskins.mixin",
|
||||||
"refmap": "hdskins.mixin.refmap.json",
|
"refmap": "hdskins.mixin.refmap.json",
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"MixinMinecraft",
|
|
||||||
"MixinGuiMainMenu",
|
"MixinGuiMainMenu",
|
||||||
"MixinImageBufferDownload",
|
"MixinImageBufferDownload",
|
||||||
"MixinPlayerInfo",
|
"MixinPlayerInfo",
|
||||||
|
|
Loading…
Reference in a new issue