Archived
0

Keep alive

This commit is contained in:
2018-04-21 09:20:16 +03:00
parent 9d22d7c91b
commit 8be8caa05a
6 changed files with 75 additions and 14 deletions

View File

@@ -4,6 +4,7 @@
*/ */
package mc.core.embedded; package mc.core.embedded;
import lombok.extern.slf4j.Slf4j;
import mc.core.Config; import mc.core.Config;
import mc.core.Player; import mc.core.Player;
import mc.core.PlayerManager; import mc.core.PlayerManager;
@@ -14,18 +15,24 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
public class InMemoryPlayerManager implements PlayerManager { @Slf4j
public class InMemoryPlayerManager implements PlayerManager, Runnable {
private List<Player> players; private List<Player> players;
private final Object lock = new Object();
@Autowired @Autowired
public InMemoryPlayerManager(Config config) { public InMemoryPlayerManager(Config config) {
final int c = config.getMaxPlayers() > 50 ? 50 : config.getMaxPlayers(); final int c = config.getMaxPlayers() > 50 ? 50 : config.getMaxPlayers();
players = Collections.synchronizedList(new ArrayList<>(c)); players = Collections.synchronizedList(new ArrayList<>(c));
(new Thread(this, "KeepAlive")).start();
} }
@Override @Override
public void addPlayer(Player player) { public void addPlayer(Player player) {
synchronized (lock) {
players.add(player); players.add(player);
lock.notify();
}
} }
@Override @Override
@@ -53,4 +60,29 @@ public class InMemoryPlayerManager implements PlayerManager {
public void bloadcastWrite(final CSPacket packet) { public void bloadcastWrite(final CSPacket packet) {
players.forEach(player -> player.getChannel().writeAndFlush(packet)); players.forEach(player -> player.getChannel().writeAndFlush(packet));
} }
@Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
synchronized (lock) {
while (players.size() == 0) {
try {
lock.wait();
} catch (InterruptedException e) {
return;
}
}
}
players.stream()
.parallel()
.forEach(player -> player.getChannel().sendKeepAlive());
try {
Thread.sleep(1);
} catch (InterruptedException e) {
return;
}
}
}
} }

View File

@@ -5,8 +5,7 @@
package mc.core.network; package mc.core.network;
public interface NetChannel { public interface NetChannel {
void write(Object obj); void sendKeepAlive();
void flush();
void writeAndFlush(Object obj);
void writeAndFlush(SCPacket pkt);
} }

View File

@@ -8,8 +8,10 @@ package mc.core.network.proto_125.netty;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.AttributeKey;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import mc.core.Location; import mc.core.Location;
import mc.core.Player;
import mc.core.PlayerManager; import mc.core.PlayerManager;
import mc.core.network.CSPacket; import mc.core.network.CSPacket;
import mc.core.Config; import mc.core.Config;
@@ -25,11 +27,18 @@ import java.util.Random;
@Slf4j @Slf4j
public class PacketHandler extends SimpleChannelInboundHandler<CSPacket> { public class PacketHandler extends SimpleChannelInboundHandler<CSPacket> {
private static final Random random = new Random(); private static final Random random = new Random();
private static final AttributeKey<Player> ATTR_PLAYER = AttributeKey.newInstance("ATTR_PLAYER");
@Autowired @Autowired
private Config config; private Config config;
@Autowired @Autowired
private PlayerManager playerManager; private PlayerManager playerManager;
@Override
public void channelInactive(ChannelHandlerContext context) throws Exception {
super.channelInactive(context);
playerManager.removePlayer(context.channel().attr(ATTR_PLAYER).get());
}
@Override @Override
protected void channelRead0(ChannelHandlerContext ctx, CSPacket packet) throws Exception { protected void channelRead0(ChannelHandlerContext ctx, CSPacket packet) throws Exception {
Optional<Method> optionalMethod = Arrays.stream(this.getClass().getDeclaredMethods()) Optional<Method> optionalMethod = Arrays.stream(this.getClass().getDeclaredMethods())
@@ -145,6 +154,7 @@ public class PacketHandler extends SimpleChannelInboundHandler<CSPacket> {
channel.write(posLookPkt); channel.write(posLookPkt);
playerManager.addPlayer(player); playerManager.addPlayer(player);
channel.attr(ATTR_PLAYER).set(player);
channel.flush(); channel.flush();
} }
} }

View File

@@ -7,23 +7,21 @@ package mc.core.network.proto_125.netty.wrappers;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import mc.core.network.NetChannel; import mc.core.network.NetChannel;
import mc.core.network.SCPacket;
import mc.core.network.proto_125.packets.KeepAlivePacket;
import mc.core.network.proto_125.packets.PingPacket;
@RequiredArgsConstructor @RequiredArgsConstructor
public class WrapperNetChannel implements NetChannel { public class WrapperNetChannel implements NetChannel {
private final Channel channel; private final Channel channel;
@Override @Override
public void write(Object obj) { public void sendKeepAlive() {
channel.write(obj); channel.writeAndFlush(new KeepAlivePacket());
} }
@Override @Override
public void flush() { public void writeAndFlush(SCPacket pkt) {
channel.flush(); channel.writeAndFlush(pkt);
}
@Override
public void writeAndFlush(Object obj) {
channel.writeAndFlush(obj);
} }
} }

View File

@@ -0,0 +1,21 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-04-21
*/
package mc.core.network.proto_125.packets;
import mc.core.network.SCPacket;
import mc.core.network.proto_125.ByteArrayOutputNetStream;
import java.util.Random;
public class KeepAlivePacket implements SCPacket {
private static final Random rand = new Random();
@Override
public byte[] toByteArray() {
ByteArrayOutputNetStream netStream = new ByteArrayOutputNetStream();
netStream.writeInt(rand.nextInt(Integer.MAX_VALUE));
return netStream.toByteArray();
}
}

View File

@@ -12,6 +12,7 @@ import mc.core.network.proto_125.packets.*;
public class PacketManager { public class PacketManager {
private static final BiMap<Integer, Class<?>> packetMap = ImmutableBiMap.<Integer, Class<?>>builder() private static final BiMap<Integer, Class<?>> packetMap = ImmutableBiMap.<Integer, Class<?>>builder()
.put(0x00, KeepAlivePacket.class)
.put(0x01, LoginPacket.class) .put(0x01, LoginPacket.class)
.put(0x02, HandshakePacket.class) .put(0x02, HandshakePacket.class)
.put(0x06, SpawnPositionPacket.class) .put(0x06, SpawnPositionPacket.class)