2019-07-17 18:00:11 +00:00
/ *
2020-01-09 03:05:42 +00:00
* Copyright ( c ) 2019 - 2020 GeyserMC . http : //geysermc.org
2019-07-17 18:00:11 +00:00
*
* 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/Geyser
* /
2019-07-11 22:39:28 +00:00
package org.geysermc.connector.network.translators ;
2020-05-28 15:43:31 +00:00
import com.github.steveice10.mc.protocol.packet.ingame.server.ServerKeepAlivePacket ;
2020-05-23 21:11:54 +00:00
import com.github.steveice10.mc.protocol.packet.ingame.server.world.ServerUpdateLightPacket ;
2020-05-28 15:43:31 +00:00
import com.github.steveice10.packetlib.packet.Packet ;
import com.nukkitx.protocol.bedrock.BedrockPacket ;
2020-05-23 21:11:54 +00:00
import it.unimi.dsi.fastutil.objects.ObjectArrayList ;
2019-12-21 17:35:48 +00:00
import org.geysermc.connector.GeyserConnector ;
2019-07-13 19:00:51 +00:00
import org.geysermc.connector.network.session.GeyserSession ;
2020-05-25 01:07:05 +00:00
import org.reflections.Reflections ;
2019-07-11 22:39:28 +00:00
2020-05-28 15:43:31 +00:00
import java.util.HashMap ;
import java.util.Map ;
2020-05-25 01:07:05 +00:00
public class PacketTranslatorRegistry < T > {
private final Map < Class < ? extends T > , PacketTranslator < ? extends T > > translators = new HashMap < > ( ) ;
2019-07-11 22:39:28 +00:00
2020-05-25 01:07:05 +00:00
public static final PacketTranslatorRegistry < Packet > JAVA_TRANSLATOR = new PacketTranslatorRegistry < > ( ) ;
public static final PacketTranslatorRegistry < BedrockPacket > BEDROCK_TRANSLATOR = new PacketTranslatorRegistry < > ( ) ;
2019-07-11 22:39:28 +00:00
2020-05-23 21:11:54 +00:00
private static final ObjectArrayList < Class < ? > > IGNORED_PACKETS = new ObjectArrayList < > ( ) ;
static {
2020-05-25 01:07:05 +00:00
Reflections ref = new Reflections ( " org.geysermc.connector.network.translators " ) ;
for ( Class < ? > clazz : ref . getTypesAnnotatedWith ( Translator . class ) ) {
Class < ? > packet = clazz . getAnnotation ( Translator . class ) . packet ( ) ;
GeyserConnector . getInstance ( ) . getLogger ( ) . debug ( " Found annotated translator: " + clazz . getCanonicalName ( ) + " : " + packet . getSimpleName ( ) ) ;
try {
if ( Packet . class . isAssignableFrom ( packet ) ) {
Class < ? extends Packet > targetPacket = ( Class < ? extends Packet > ) packet ;
PacketTranslator < ? extends Packet > translator = ( PacketTranslator < ? extends Packet > ) clazz . newInstance ( ) ;
JAVA_TRANSLATOR . translators . put ( targetPacket , translator ) ;
} else if ( BedrockPacket . class . isAssignableFrom ( packet ) ) {
Class < ? extends BedrockPacket > targetPacket = ( Class < ? extends BedrockPacket > ) packet ;
PacketTranslator < ? extends BedrockPacket > translator = ( PacketTranslator < ? extends BedrockPacket > ) clazz . newInstance ( ) ;
BEDROCK_TRANSLATOR . translators . put ( targetPacket , translator ) ;
} else {
GeyserConnector . getInstance ( ) . getLogger ( ) . error ( " Class " + clazz . getCanonicalName ( ) + " is annotated as a translator but has an invalid target packet. " ) ;
}
} catch ( InstantiationException | IllegalAccessException e ) {
GeyserConnector . getInstance ( ) . getLogger ( ) . error ( " Could not instantiate annotated translator " + clazz . getCanonicalName ( ) + " . " ) ;
}
}
2020-05-28 15:43:31 +00:00
IGNORED_PACKETS . add ( ServerKeepAlivePacket . class ) ; // Handled by MCProtocolLib
IGNORED_PACKETS . add ( ServerUpdateLightPacket . class ) ; // Light is handled on Bedrock for us
2020-05-23 21:11:54 +00:00
}
2020-05-25 01:07:05 +00:00
private PacketTranslatorRegistry ( ) {
2019-07-11 22:39:28 +00:00
}
2020-05-25 01:07:05 +00:00
public static void init ( ) {
// no-op
2019-07-24 20:12:42 +00:00
}
2020-03-24 04:03:33 +00:00
@SuppressWarnings ( " unchecked " )
2019-09-25 21:52:28 +00:00
public < P extends T > boolean translate ( Class < ? extends P > clazz , P packet , GeyserSession session ) {
2019-10-02 20:45:29 +00:00
if ( ! session . getUpstream ( ) . isClosed ( ) & & ! session . isClosed ( ) ) {
try {
2020-05-25 01:07:05 +00:00
if ( translators . containsKey ( clazz ) ) {
( ( PacketTranslator < P > ) translators . get ( clazz ) ) . translate ( packet , session ) ;
2019-10-02 20:45:29 +00:00
return true ;
2020-04-12 09:37:31 +00:00
} else {
2020-05-23 21:11:54 +00:00
if ( ! IGNORED_PACKETS . contains ( clazz ) )
GeyserConnector . getInstance ( ) . getLogger ( ) . debug ( " Could not find packet for " + ( packet . toString ( ) . length ( ) > 25 ? packet . getClass ( ) . getSimpleName ( ) : packet ) ) ;
2019-10-02 20:45:29 +00:00
}
} catch ( Throwable ex ) {
2019-12-21 17:35:48 +00:00
GeyserConnector . getInstance ( ) . getLogger ( ) . error ( " Could not translate packet " + packet . getClass ( ) . getSimpleName ( ) , ex ) ;
2019-10-02 20:45:29 +00:00
ex . printStackTrace ( ) ;
2019-07-29 22:20:48 +00:00
}
2019-07-11 22:39:28 +00:00
}
2019-09-25 21:52:28 +00:00
return false ;
2019-07-11 22:39:28 +00:00
}
}