mirror of
https://github.com/GeyserMC/Floodgate.git
synced 2026-01-06 15:42:03 +00:00
Started working on moving from Guice to Avaje Inject
This commit is contained in:
@@ -26,15 +26,8 @@
|
||||
package org.geysermc.floodgate;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Module;
|
||||
import com.velocitypowered.api.plugin.annotation.DataDirectory;
|
||||
import java.nio.file.Path;
|
||||
import org.geysermc.floodgate.module.CommandModule;
|
||||
import org.geysermc.floodgate.module.PluginMessageModule;
|
||||
import org.geysermc.floodgate.module.ProxyCommonModule;
|
||||
import org.geysermc.floodgate.module.VelocityAddonModule;
|
||||
import org.geysermc.floodgate.module.VelocityListenerModule;
|
||||
import org.geysermc.floodgate.module.VelocityPlatformModule;
|
||||
import org.geysermc.floodgate.util.ReflectionUtils;
|
||||
|
||||
public class VelocityPlatform extends FloodgatePlatform {
|
||||
@@ -46,20 +39,7 @@ public class VelocityPlatform extends FloodgatePlatform {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Module[] loadStageModules() {
|
||||
return new Module[]{
|
||||
new ProxyCommonModule(dataDirectory),
|
||||
new VelocityPlatformModule(getGuice())
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Module[] postEnableStageModules() {
|
||||
return new Module[]{
|
||||
new CommandModule(),
|
||||
new VelocityListenerModule(),
|
||||
new VelocityAddonModule(),
|
||||
new PluginMessageModule()
|
||||
};
|
||||
boolean isProxy() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,11 +25,12 @@
|
||||
|
||||
package org.geysermc.floodgate.addon.data;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.util.AttributeKey;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import jakarta.inject.Singleton;
|
||||
import org.geysermc.floodgate.api.ProxyFloodgateApi;
|
||||
import org.geysermc.floodgate.api.inject.InjectorAddon;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
@@ -37,32 +38,33 @@ import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.config.ProxyFloodgateConfig;
|
||||
import org.geysermc.floodgate.player.FloodgateHandshakeHandler;
|
||||
|
||||
@Singleton
|
||||
public final class VelocityDataAddon implements InjectorAddon {
|
||||
@Inject private FloodgateHandshakeHandler handshakeHandler;
|
||||
@Inject private ProxyFloodgateConfig config;
|
||||
@Inject private ProxyFloodgateApi api;
|
||||
@Inject private ProxyServer proxy;
|
||||
@Inject private FloodgateLogger logger;
|
||||
@Inject FloodgateHandshakeHandler handshakeHandler;
|
||||
@Inject ProxyFloodgateConfig config;
|
||||
@Inject ProxyFloodgateApi api;
|
||||
@Inject ProxyServer proxy;
|
||||
@Inject FloodgateLogger logger;
|
||||
|
||||
@Inject
|
||||
@Named("packetHandler")
|
||||
private String packetHandler;
|
||||
String packetHandler;
|
||||
|
||||
@Inject
|
||||
@Named("packetDecoder")
|
||||
private String packetDecoder;
|
||||
String packetDecoder;
|
||||
|
||||
@Inject
|
||||
@Named("packetEncoder")
|
||||
private String packetEncoder;
|
||||
String packetEncoder;
|
||||
|
||||
@Inject
|
||||
@Named("kickMessageAttribute")
|
||||
private AttributeKey<String> kickMessageAttribute;
|
||||
AttributeKey<String> kickMessageAttribute;
|
||||
|
||||
@Inject
|
||||
@Named("playerAttribute")
|
||||
private AttributeKey<FloodgatePlayer> playerAttribute;
|
||||
AttributeKey<FloodgatePlayer> playerAttribute;
|
||||
|
||||
@Override
|
||||
public void onInject(Channel channel, boolean toServer) {
|
||||
|
||||
@@ -33,12 +33,14 @@ import static org.geysermc.floodgate.util.ReflectionUtils.invoke;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import jakarta.inject.Singleton;
|
||||
import java.lang.reflect.Method;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.geysermc.floodgate.inject.CommonPlatformInjector;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Singleton
|
||||
public final class VelocityInjector extends CommonPlatformInjector {
|
||||
private final ProxyServer server;
|
||||
|
||||
|
||||
@@ -34,8 +34,6 @@ import static org.geysermc.floodgate.util.ReflectionUtils.getValue;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.name.Named;
|
||||
import com.velocitypowered.api.event.PostOrder;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.DisconnectEvent;
|
||||
@@ -47,6 +45,9 @@ import com.velocitypowered.api.util.GameProfile;
|
||||
import com.velocitypowered.api.util.GameProfile.Property;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.util.AttributeKey;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
import jakarta.inject.Singleton;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
@@ -56,8 +57,11 @@ import org.geysermc.floodgate.api.ProxyFloodgateApi;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.api.player.FloodgatePlayer;
|
||||
import org.geysermc.floodgate.config.ProxyFloodgateConfig;
|
||||
import org.geysermc.floodgate.register.ListenerRegister;
|
||||
import org.geysermc.floodgate.util.LanguageManager;
|
||||
|
||||
@ListenerRegister.Listener
|
||||
@Singleton
|
||||
public final class VelocityListener {
|
||||
private static final Field INITIAL_MINECRAFT_CONNECTION;
|
||||
private static final Field INITIAL_CONNECTION_DELEGATE;
|
||||
@@ -90,18 +94,18 @@ public final class VelocityListener {
|
||||
.expireAfterAccess(20, TimeUnit.SECONDS)
|
||||
.build();
|
||||
|
||||
@Inject private ProxyFloodgateConfig config;
|
||||
@Inject private ProxyFloodgateApi api;
|
||||
@Inject private LanguageManager languageManager;
|
||||
@Inject private FloodgateLogger logger;
|
||||
@Inject ProxyFloodgateConfig config;
|
||||
@Inject ProxyFloodgateApi api;
|
||||
@Inject LanguageManager languageManager;
|
||||
@Inject FloodgateLogger logger;
|
||||
|
||||
@Inject
|
||||
@Named("playerAttribute")
|
||||
private AttributeKey<FloodgatePlayer> playerAttribute;
|
||||
AttributeKey<FloodgatePlayer> playerAttribute;
|
||||
|
||||
@Inject
|
||||
@Named("kickMessageAttribute")
|
||||
private AttributeKey<String> kickMessageAttribute;
|
||||
AttributeKey<String> kickMessageAttribute;
|
||||
|
||||
@Subscribe(order = PostOrder.EARLY)
|
||||
public void onPreLogin(PreLoginEvent event) {
|
||||
|
||||
@@ -27,8 +27,8 @@ package org.geysermc.floodgate.logger;
|
||||
|
||||
import static org.geysermc.floodgate.util.MessageFormatter.format;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import org.apache.logging.log4j.Level;
|
||||
import org.apache.logging.log4j.core.config.Configurator;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
@@ -38,11 +38,11 @@ import org.slf4j.Logger;
|
||||
|
||||
@Singleton
|
||||
public final class Slf4jFloodgateLogger implements FloodgateLogger {
|
||||
@Inject private Logger logger;
|
||||
@Inject Logger logger;
|
||||
private LanguageManager languageManager;
|
||||
|
||||
@Inject
|
||||
private void init(LanguageManager languageManager, FloodgateConfig config) {
|
||||
void init(LanguageManager languageManager, FloodgateConfig config) {
|
||||
this.languageManager = languageManager;
|
||||
if (config.isDebug() && !logger.isDebugEnabled()) {
|
||||
Configurator.setLevel(logger.getName(), Level.DEBUG);
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.module;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.multibindings.ProvidesIntoSet;
|
||||
import org.geysermc.floodgate.addon.AddonManagerAddon;
|
||||
import org.geysermc.floodgate.addon.DebugAddon;
|
||||
import org.geysermc.floodgate.addon.PacketHandlerAddon;
|
||||
import org.geysermc.floodgate.addon.data.VelocityDataAddon;
|
||||
import org.geysermc.floodgate.api.inject.InjectorAddon;
|
||||
import org.geysermc.floodgate.register.AddonRegister;
|
||||
|
||||
public final class VelocityAddonModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(AddonRegister.class).asEagerSingleton();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@ProvidesIntoSet
|
||||
public InjectorAddon managerAddon() {
|
||||
return new AddonManagerAddon();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@ProvidesIntoSet
|
||||
public InjectorAddon dataAddon() {
|
||||
return new VelocityDataAddon();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@ProvidesIntoSet
|
||||
public InjectorAddon debugAddon() {
|
||||
return new DebugAddon();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@ProvidesIntoSet
|
||||
public InjectorAddon packetHandlerAddon() {
|
||||
return new PacketHandlerAddon();
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2022 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Floodgate
|
||||
*/
|
||||
|
||||
package org.geysermc.floodgate.module;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import com.google.inject.multibindings.ProvidesIntoSet;
|
||||
import org.geysermc.floodgate.listener.VelocityListener;
|
||||
import org.geysermc.floodgate.platform.pluginmessage.PluginMessageUtils;
|
||||
import org.geysermc.floodgate.register.ListenerRegister;
|
||||
|
||||
public final class VelocityListenerModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(new TypeLiteral<ListenerRegister<Object>>() {}).asEagerSingleton();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@ProvidesIntoSet
|
||||
public Object velocityListener() {
|
||||
return new VelocityListener();
|
||||
}
|
||||
|
||||
@Singleton
|
||||
@ProvidesIntoSet
|
||||
public Object pluginMessageListener(PluginMessageUtils handler) {
|
||||
return handler; // Plugin message handler is also the listener
|
||||
}
|
||||
}
|
||||
@@ -27,64 +27,41 @@ package org.geysermc.floodgate.module;
|
||||
|
||||
import cloud.commandframework.CommandManager;
|
||||
import cloud.commandframework.execution.CommandExecutionCoordinator;
|
||||
import cloud.commandframework.velocity.CloudInjectionModule;
|
||||
import cloud.commandframework.velocity.VelocityCommandManager;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.Singleton;
|
||||
import com.google.inject.name.Named;
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.event.EventManager;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import io.avaje.inject.Bean;
|
||||
import io.avaje.inject.Factory;
|
||||
import jakarta.inject.Named;
|
||||
import jakarta.inject.Singleton;
|
||||
import org.geysermc.floodgate.VelocityPlugin;
|
||||
import org.geysermc.floodgate.api.logger.FloodgateLogger;
|
||||
import org.geysermc.floodgate.inject.CommonPlatformInjector;
|
||||
import org.geysermc.floodgate.inject.velocity.VelocityInjector;
|
||||
import org.geysermc.floodgate.listener.VelocityListenerRegistration;
|
||||
import org.geysermc.floodgate.logger.Slf4jFloodgateLogger;
|
||||
import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.platform.listener.ListenerRegistration;
|
||||
import org.geysermc.floodgate.platform.pluginmessage.PluginMessageUtils;
|
||||
import org.geysermc.floodgate.platform.util.PlatformUtils;
|
||||
import org.geysermc.floodgate.player.FloodgateCommandPreprocessor;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.geysermc.floodgate.pluginmessage.PluginMessageManager;
|
||||
import org.geysermc.floodgate.pluginmessage.PluginMessageRegistration;
|
||||
import org.geysermc.floodgate.pluginmessage.VelocityPluginMessageRegistration;
|
||||
import org.geysermc.floodgate.pluginmessage.VelocityPluginMessageUtils;
|
||||
import org.geysermc.floodgate.skin.SkinApplier;
|
||||
import org.geysermc.floodgate.util.VelocityCommandUtil;
|
||||
import org.geysermc.floodgate.util.VelocityPlatformUtils;
|
||||
import org.geysermc.floodgate.util.VelocitySkinApplier;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public final class VelocityPlatformModule extends AbstractModule {
|
||||
private final Injector guice;
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(CommandUtil.class).to(VelocityCommandUtil.class);
|
||||
bind(PlatformUtils.class).to(VelocityPlatformUtils.class);
|
||||
bind(FloodgateLogger.class).to(Slf4jFloodgateLogger.class);
|
||||
bind(SkinApplier.class).to(VelocitySkinApplier.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Factory
|
||||
public final class VelocityPlatformModule {
|
||||
@Bean
|
||||
@Singleton
|
||||
public CommandManager<UserAudience> commandManager(CommandUtil commandUtil) {
|
||||
Injector child = guice.createChildInjector(new CloudInjectionModule<>(
|
||||
UserAudience.class,
|
||||
public CommandManager<UserAudience> commandManager(CommandUtil commandUtil, ProxyServer proxy) {
|
||||
CommandManager<UserAudience> commandManager = new VelocityCommandManager<>(
|
||||
null,
|
||||
proxy,
|
||||
CommandExecutionCoordinator.simpleCoordinator(),
|
||||
commandUtil::getUserAudience,
|
||||
audience -> (CommandSource) audience.source()
|
||||
));
|
||||
|
||||
CommandManager<UserAudience> commandManager =
|
||||
child.getInstance(new Key<VelocityCommandManager<UserAudience>>() {});
|
||||
|
||||
);
|
||||
commandManager.registerCommandPreProcessor(new FloodgateCommandPreprocessor<>(commandUtil));
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
|
||||
package org.geysermc.floodgate.pluginmessage;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.PluginMessageEvent;
|
||||
import com.velocitypowered.api.event.connection.PluginMessageEvent.ForwardResult;
|
||||
@@ -35,6 +34,7 @@ import com.velocitypowered.api.proxy.ServerConnection;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelIdentifier;
|
||||
import com.velocitypowered.api.proxy.messages.ChannelMessageSource;
|
||||
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
|
||||
import jakarta.inject.Inject;
|
||||
import java.util.UUID;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
@@ -25,10 +25,11 @@
|
||||
|
||||
package org.geysermc.floodgate.util;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.velocitypowered.api.command.CommandSource;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import java.util.Collection;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
@@ -39,11 +40,14 @@ import org.geysermc.floodgate.platform.command.CommandUtil;
|
||||
import org.geysermc.floodgate.player.UserAudience;
|
||||
import org.geysermc.floodgate.player.UserAudience.ConsoleAudience;
|
||||
import org.geysermc.floodgate.player.UserAudience.PlayerAudience;
|
||||
import org.geysermc.floodgate.register.ListenerRegister;
|
||||
|
||||
@ListenerRegister.Listener
|
||||
@Singleton
|
||||
public final class VelocityCommandUtil extends CommandUtil {
|
||||
private static UserAudience console;
|
||||
|
||||
@Inject private ProxyServer server;
|
||||
@Inject ProxyServer server;
|
||||
|
||||
@Inject
|
||||
public VelocityCommandUtil(LanguageManager manager, FloodgateApi api) {
|
||||
|
||||
@@ -25,14 +25,13 @@
|
||||
|
||||
package org.geysermc.floodgate.util;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import jakarta.inject.Inject;
|
||||
import org.geysermc.floodgate.platform.util.PlatformUtils;
|
||||
|
||||
public final class VelocityPlatformUtils extends PlatformUtils {
|
||||
@Inject
|
||||
private ProxyServer server;
|
||||
@Inject ProxyServer server;
|
||||
|
||||
@Override
|
||||
public AuthType authType() {
|
||||
|
||||
@@ -25,10 +25,10 @@
|
||||
|
||||
package org.geysermc.floodgate.util;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import com.velocitypowered.api.util.GameProfile.Property;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
@@ -42,8 +42,8 @@ import org.geysermc.floodgate.skin.SkinDataImpl;
|
||||
|
||||
@Singleton
|
||||
public class VelocitySkinApplier implements SkinApplier {
|
||||
@Inject private ProxyServer server;
|
||||
@Inject private EventBus eventBus;
|
||||
@Inject ProxyServer server;
|
||||
@Inject EventBus eventBus;
|
||||
|
||||
@Override
|
||||
public void applySkin(@NonNull FloodgatePlayer floodgatePlayer, @NonNull SkinData skinData) {
|
||||
|
||||
Reference in New Issue
Block a user