diff --git a/core/src/main/java/mc/core/embedded/FakePlayerManager.java b/core/src/main/java/mc/core/embedded/FakePlayerManager.java index 5743632..f90255b 100644 --- a/core/src/main/java/mc/core/embedded/FakePlayerManager.java +++ b/core/src/main/java/mc/core/embedded/FakePlayerManager.java @@ -16,9 +16,6 @@ import java.util.Optional; public class FakePlayerManager implements PlayerManager { public static class FakeNetChannet implements NetChannel { - @Override - public void sendKeepAlive() { - } @Override public void sendTimeUpdate(long time, long age) { diff --git a/core/src/main/java/mc/core/network/BroadcastNetChannel.java b/core/src/main/java/mc/core/network/BroadcastNetChannel.java index 3f5e7bb..ed15fab 100644 --- a/core/src/main/java/mc/core/network/BroadcastNetChannel.java +++ b/core/src/main/java/mc/core/network/BroadcastNetChannel.java @@ -16,11 +16,6 @@ import java.util.stream.Stream; public class BroadcastNetChannel implements NetChannel { private final Stream playerStream; - @Override - public void sendKeepAlive() { - playerStream.forEach(player -> player.getChannel().sendKeepAlive()); - } - @Override public void sendTimeUpdate(final long time, final long age) { playerStream.forEach(player -> player.getChannel().sendTimeUpdate(time, age)); diff --git a/core/src/main/java/mc/core/network/NetChannel.java b/core/src/main/java/mc/core/network/NetChannel.java index 69c05c7..bfd6899 100644 --- a/core/src/main/java/mc/core/network/NetChannel.java +++ b/core/src/main/java/mc/core/network/NetChannel.java @@ -9,7 +9,6 @@ import mc.core.text.Text; import mc.core.text.Title; public interface NetChannel { - void sendKeepAlive(); void sendTimeUpdate(long time, long age); default void sendChatMessage(Text text) { sendChatMessage(text, MessageType.CHAT_MESSAGE); diff --git a/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerManager.java b/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerManager.java index 636460b..2f4780d 100644 --- a/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerManager.java +++ b/h2_playermanager/src/main/java/mc/core/h2db/H2PlayerManager.java @@ -24,22 +24,14 @@ import static org.slf4j.helpers.MessageFormatter.format; @Slf4j @Component -public class H2PlayerManager implements PlayerManager, Runnable { +public class H2PlayerManager implements PlayerManager { @Setter @Autowired private H2PlayerDAO h2playerDao; private List playerList = Collections.synchronizedList(new ArrayList<>()); - private final Object lock = new Object(); - @Setter - private int keepAliveInterval = 1; @Autowired private World world; - @PostConstruct - public void init() { - (new Thread(this, "KeepAlive")).start(); - } - @Override public Player createPlayer(String name, EntityLocation location, World world) { //TODO в дальнейшем следует в этом методе только имплементацию Player @@ -65,11 +57,8 @@ public class H2PlayerManager implements PlayerManager, Runnable { public void joinServer(Player player) { //TODO в дальнейшем следует именно этому методу передать функции инсерта в БД H2Player h2Player = (H2Player) player; - synchronized (lock) { - playerList.add(h2Player); - h2Player.setOnline(true); - lock.notify(); - } + playerList.add(h2Player); + h2Player.setOnline(true); } @Override @@ -79,13 +68,9 @@ public class H2PlayerManager implements PlayerManager, Runnable { h2playerDao.update(h2Player); } catch (SQLException e) { log.error(format("Update player '{}'", h2Player.getName()).getMessage(), e); - synchronized (lock) { - playerList.remove(h2Player); - } + playerList.remove(h2Player); } finally { - h2Player.setId(0); h2Player.setOnline(false); - h2Player.setWorld(null); h2Player.getLoadedChunks().clear(); } } @@ -153,27 +138,4 @@ public class H2PlayerManager implements PlayerManager, Runnable { return h2Player; } } - - @Override - public void run() { - while (!Thread.currentThread().isInterrupted()) { - while(getCountPlayers() == 0) { - synchronized (lock) { - try { - lock.wait(); - } catch (InterruptedException e) { - return; - } - } - } - - getBroadcastChannel().sendKeepAlive(); - - try { - Thread.sleep(keepAliveInterval); - } catch (InterruptedException e) { - return; - } - } - } } diff --git a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/KeepAliveThread.java b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/KeepAliveThread.java new file mode 100644 index 0000000..afa4607 --- /dev/null +++ b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/KeepAliveThread.java @@ -0,0 +1,49 @@ +package mc.core.network.proto_1_12_2.netty; + +import lombok.Getter; +import lombok.Setter; +import mc.core.network.proto_1_12_2.packets.KeepAlivePacket; +import mc.core.player.PlayerManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Random; + +@Component +public class KeepAliveThread extends Thread { + private static final Random RAND = new Random(); + private final Object lock = new Object(); + @Autowired + private PlayerManager playerManager; + @Setter + private int interval = 10; + + public void notifyLock() { + synchronized (lock) { + lock.notify(); + } + } + + @Override + public void run() { + while (!Thread.currentThread().isInterrupted()) { + while(playerManager.getCountPlayers() == 0) { + synchronized (lock) { + try { + lock.wait(); + } catch (InterruptedException e) { + return; + } + } + } + + playerManager.getBroadcastChannel().writeAndFlush(new KeepAlivePacket(RAND.nextLong())); + + try { + Thread.sleep(interval); + } catch (InterruptedException e) { + return; + } + } + } +} diff --git a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/NettyServer.java b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/NettyServer.java index 057a425..7df1c3f 100644 --- a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/NettyServer.java +++ b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/NettyServer.java @@ -1,10 +1,7 @@ -/* - * DmitriyMX - * 2018-06-10 - */ package mc.core.network.proto_1_12_2.netty; import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; @@ -22,16 +19,20 @@ import mc.core.network.proto_1_12_2.packets.StatusResponsePacket; import mc.core.player.Player; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Component; import java.util.Map; @Slf4j +@Component public class NettyServer implements Server { public static final AttributeKey ATTR_STATE = AttributeKey.newInstance("ATTR_STATE"); public static final AttributeKey ATTR_PLAYER = AttributeKey.newInstance("ATTR_PLAYER"); @Autowired - private ApplicationContext applicationContext; + private ApplicationContext context; + @Autowired + private KeepAliveThread keepAliveThread; @Setter private String host; @Setter @@ -44,7 +45,7 @@ public class NettyServer implements Server { return new ChannelInitializer() { @Override protected void initChannel(SocketChannel socketChannel) { - Map beans = applicationContext.getBeansOfType(ChannelHandler.class); + Map beans = context.getBeansOfType(ChannelHandler.class); beans.forEach(socketChannel.pipeline()::addLast); } }; @@ -73,7 +74,9 @@ public class NettyServer implements Server { log.info("Start server: {}:{}", host, port); try { - serverBootstrap.bind(host, port).sync().channel().closeFuture().sync(); + ChannelFuture channelFuture = serverBootstrap.bind(host, port).sync(); + keepAliveThread.start(); + channelFuture.channel().closeFuture().sync(); } catch (InterruptedException e) { throw new StartServerException(e); } @@ -82,6 +85,7 @@ public class NettyServer implements Server { @Override public void stop() { log.info("Server shutdown"); + keepAliveThread.interrupt(); workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } diff --git a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java index 084d7f7..829392f 100644 --- a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java +++ b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/handlers/LoginHandler.java @@ -1,7 +1,3 @@ -/* - * DmitriyMX - * 2018-06-23 - */ package mc.core.network.proto_1_12_2.netty.handlers; import io.netty.channel.Channel; @@ -10,6 +6,7 @@ import mc.core.eventbus.events.CS_PlayerMoveEvent; import mc.core.eventbus.EventBusGetter; import mc.core.network.proto_1_12_2.State; import mc.core.network.proto_1_12_2.TeleportManager; +import mc.core.network.proto_1_12_2.netty.KeepAliveThread; import mc.core.network.proto_1_12_2.netty.wrappers.WrapperNetChannel; import mc.core.network.proto_1_12_2.packets.*; import mc.core.player.Player; @@ -32,6 +29,8 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand @Autowired private PlayerManager playerManager; @Autowired + private KeepAliveThread keepAliveThread; + @Autowired private World world; @Handler @@ -131,6 +130,7 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand channel.writeAndFlush(pkt5); playerManager.joinServer(player); + keepAliveThread.notifyLock(); CS_PlayerMoveEvent event = new CS_PlayerMoveEvent(player, player.getLocation()); event.setNewLocation(player.getLocation()); diff --git a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/wrappers/WrapperNetChannel.java b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/wrappers/WrapperNetChannel.java index 192edd6..fd53188 100644 --- a/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/wrappers/WrapperNetChannel.java +++ b/proto_1.12.2_netty/src/main/java/mc/core/network/proto_1_12_2/netty/wrappers/WrapperNetChannel.java @@ -20,14 +20,8 @@ import java.util.Random; @RequiredArgsConstructor public class WrapperNetChannel implements NetChannel { - private static final Random RAND = new Random(); private final Channel channel; - @Override - public void sendKeepAlive() { - writeAndFlush(new KeepAlivePacket(RAND.nextLong())); - } - @Override public void sendTimeUpdate(long time, long age) { writeAndFlush(new TimeUpdatePacket(time, age));