Archived
0

переведен функционал keep alive на сетевой модуль

This commit is contained in:
2018-09-16 20:47:37 +03:00
parent cb8566ae02
commit 3ee1b16c92
8 changed files with 68 additions and 68 deletions

View File

@@ -16,9 +16,6 @@ import java.util.Optional;
public class FakePlayerManager implements PlayerManager { public class FakePlayerManager implements PlayerManager {
public static class FakeNetChannet implements NetChannel { public static class FakeNetChannet implements NetChannel {
@Override
public void sendKeepAlive() {
}
@Override @Override
public void sendTimeUpdate(long time, long age) { public void sendTimeUpdate(long time, long age) {

View File

@@ -16,11 +16,6 @@ import java.util.stream.Stream;
public class BroadcastNetChannel implements NetChannel { public class BroadcastNetChannel implements NetChannel {
private final Stream<Player> playerStream; private final Stream<Player> playerStream;
@Override
public void sendKeepAlive() {
playerStream.forEach(player -> player.getChannel().sendKeepAlive());
}
@Override @Override
public void sendTimeUpdate(final long time, final long age) { public void sendTimeUpdate(final long time, final long age) {
playerStream.forEach(player -> player.getChannel().sendTimeUpdate(time, age)); playerStream.forEach(player -> player.getChannel().sendTimeUpdate(time, age));

View File

@@ -9,7 +9,6 @@ import mc.core.text.Text;
import mc.core.text.Title; import mc.core.text.Title;
public interface NetChannel { public interface NetChannel {
void sendKeepAlive();
void sendTimeUpdate(long time, long age); void sendTimeUpdate(long time, long age);
default void sendChatMessage(Text text) { default void sendChatMessage(Text text) {
sendChatMessage(text, MessageType.CHAT_MESSAGE); sendChatMessage(text, MessageType.CHAT_MESSAGE);

View File

@@ -24,22 +24,14 @@ import static org.slf4j.helpers.MessageFormatter.format;
@Slf4j @Slf4j
@Component @Component
public class H2PlayerManager implements PlayerManager, Runnable { public class H2PlayerManager implements PlayerManager {
@Setter @Setter
@Autowired @Autowired
private H2PlayerDAO h2playerDao; private H2PlayerDAO h2playerDao;
private List<H2Player> playerList = Collections.synchronizedList(new ArrayList<>()); private List<H2Player> playerList = Collections.synchronizedList(new ArrayList<>());
private final Object lock = new Object();
@Setter
private int keepAliveInterval = 1;
@Autowired @Autowired
private World world; private World world;
@PostConstruct
public void init() {
(new Thread(this, "KeepAlive")).start();
}
@Override @Override
public Player createPlayer(String name, EntityLocation location, World world) { public Player createPlayer(String name, EntityLocation location, World world) {
//TODO в дальнейшем следует в этом методе только имплементацию Player //TODO в дальнейшем следует в этом методе только имплементацию Player
@@ -65,11 +57,8 @@ public class H2PlayerManager implements PlayerManager, Runnable {
public void joinServer(Player player) { public void joinServer(Player player) {
//TODO в дальнейшем следует именно этому методу передать функции инсерта в БД //TODO в дальнейшем следует именно этому методу передать функции инсерта в БД
H2Player h2Player = (H2Player) player; H2Player h2Player = (H2Player) player;
synchronized (lock) { playerList.add(h2Player);
playerList.add(h2Player); h2Player.setOnline(true);
h2Player.setOnline(true);
lock.notify();
}
} }
@Override @Override
@@ -79,13 +68,9 @@ public class H2PlayerManager implements PlayerManager, Runnable {
h2playerDao.update(h2Player); h2playerDao.update(h2Player);
} catch (SQLException e) { } catch (SQLException e) {
log.error(format("Update player '{}'", h2Player.getName()).getMessage(), e); log.error(format("Update player '{}'", h2Player.getName()).getMessage(), e);
synchronized (lock) { playerList.remove(h2Player);
playerList.remove(h2Player);
}
} finally { } finally {
h2Player.setId(0);
h2Player.setOnline(false); h2Player.setOnline(false);
h2Player.setWorld(null);
h2Player.getLoadedChunks().clear(); h2Player.getLoadedChunks().clear();
} }
} }
@@ -153,27 +138,4 @@ public class H2PlayerManager implements PlayerManager, Runnable {
return h2Player; 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;
}
}
}
} }

View File

@@ -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;
}
}
}
}

View File

@@ -1,10 +1,7 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-06-10
*/
package mc.core.network.proto_1_12_2.netty; package mc.core.network.proto_1_12_2.netty;
import io.netty.bootstrap.ServerBootstrap; import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup; 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 mc.core.player.Player;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.util.Map; import java.util.Map;
@Slf4j @Slf4j
@Component
public class NettyServer implements Server { public class NettyServer implements Server {
public static final AttributeKey<State> ATTR_STATE = AttributeKey.newInstance("ATTR_STATE"); public static final AttributeKey<State> ATTR_STATE = AttributeKey.newInstance("ATTR_STATE");
public static final AttributeKey<Player> ATTR_PLAYER = AttributeKey.newInstance("ATTR_PLAYER"); public static final AttributeKey<Player> ATTR_PLAYER = AttributeKey.newInstance("ATTR_PLAYER");
@Autowired @Autowired
private ApplicationContext applicationContext; private ApplicationContext context;
@Autowired
private KeepAliveThread keepAliveThread;
@Setter @Setter
private String host; private String host;
@Setter @Setter
@@ -44,7 +45,7 @@ public class NettyServer implements Server {
return new ChannelInitializer<SocketChannel>() { return new ChannelInitializer<SocketChannel>() {
@Override @Override
protected void initChannel(SocketChannel socketChannel) { protected void initChannel(SocketChannel socketChannel) {
Map<String, ChannelHandler> beans = applicationContext.getBeansOfType(ChannelHandler.class); Map<String, ChannelHandler> beans = context.getBeansOfType(ChannelHandler.class);
beans.forEach(socketChannel.pipeline()::addLast); beans.forEach(socketChannel.pipeline()::addLast);
} }
}; };
@@ -73,7 +74,9 @@ public class NettyServer implements Server {
log.info("Start server: {}:{}", host, port); log.info("Start server: {}:{}", host, port);
try { 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) { } catch (InterruptedException e) {
throw new StartServerException(e); throw new StartServerException(e);
} }
@@ -82,6 +85,7 @@ public class NettyServer implements Server {
@Override @Override
public void stop() { public void stop() {
log.info("Server shutdown"); log.info("Server shutdown");
keepAliveThread.interrupt();
workerGroup.shutdownGracefully(); workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully(); bossGroup.shutdownGracefully();
} }

View File

@@ -1,7 +1,3 @@
/*
* DmitriyMX <dimon550@gmail.com>
* 2018-06-23
*/
package mc.core.network.proto_1_12_2.netty.handlers; package mc.core.network.proto_1_12_2.netty.handlers;
import io.netty.channel.Channel; import io.netty.channel.Channel;
@@ -10,6 +6,7 @@ import mc.core.eventbus.events.CS_PlayerMoveEvent;
import mc.core.eventbus.EventBusGetter; import mc.core.eventbus.EventBusGetter;
import mc.core.network.proto_1_12_2.State; 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.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.netty.wrappers.WrapperNetChannel;
import mc.core.network.proto_1_12_2.packets.*; import mc.core.network.proto_1_12_2.packets.*;
import mc.core.player.Player; import mc.core.player.Player;
@@ -32,6 +29,8 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand
@Autowired @Autowired
private PlayerManager playerManager; private PlayerManager playerManager;
@Autowired @Autowired
private KeepAliveThread keepAliveThread;
@Autowired
private World world; private World world;
@Handler @Handler
@@ -131,6 +130,7 @@ public class LoginHandler extends AbstractStateHandler implements LoginStateHand
channel.writeAndFlush(pkt5); channel.writeAndFlush(pkt5);
playerManager.joinServer(player); playerManager.joinServer(player);
keepAliveThread.notifyLock();
CS_PlayerMoveEvent event = new CS_PlayerMoveEvent(player, player.getLocation()); CS_PlayerMoveEvent event = new CS_PlayerMoveEvent(player, player.getLocation());
event.setNewLocation(player.getLocation()); event.setNewLocation(player.getLocation());

View File

@@ -20,14 +20,8 @@ import java.util.Random;
@RequiredArgsConstructor @RequiredArgsConstructor
public class WrapperNetChannel implements NetChannel { public class WrapperNetChannel implements NetChannel {
private static final Random RAND = new Random();
private final Channel channel; private final Channel channel;
@Override
public void sendKeepAlive() {
writeAndFlush(new KeepAlivePacket(RAND.nextLong()));
}
@Override @Override
public void sendTimeUpdate(long time, long age) { public void sendTimeUpdate(long time, long age) {
writeAndFlush(new TimeUpdatePacket(time, age)); writeAndFlush(new TimeUpdatePacket(time, age));