GameServer.java 4.18 KB
Newer Older
Melledy's avatar
Melledy committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package emu.grasscutter.server.game;

import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;

import emu.grasscutter.GenshinConstants;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.GenshinPlayer;
import emu.grasscutter.game.dungeons.DungeonManager;
import emu.grasscutter.game.gacha.GachaManager;
import emu.grasscutter.game.managers.ChatManager;
import emu.grasscutter.game.managers.InventoryManager;
import emu.grasscutter.game.managers.MultiplayerManager;
import emu.grasscutter.game.shop.ShopManager;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail;
import emu.grasscutter.netty.MihoyoKcpServer;

public class GameServer extends MihoyoKcpServer {
	private final InetSocketAddress address;
	private final GameServerPacketHandler packetHandler;
	private final Timer gameLoop;
	
	private final Map<Integer, GenshinPlayer> players;
	
	private final ChatManager chatManager;
	private final InventoryManager inventoryManager;
	private final GachaManager gachaManager;
	private final ShopManager shopManager;
	private final MultiplayerManager multiplayerManager;
	private final DungeonManager dungeonManager;
	
	public GameServer(InetSocketAddress address) {
		super(address);
		this.setServerInitializer(new GameServerInitializer(this));
		this.address = address;
		this.packetHandler = new GameServerPacketHandler(PacketHandler.class);
		this.players = new ConcurrentHashMap<>();
		
		this.chatManager = new ChatManager(this);
		this.inventoryManager = new InventoryManager(this);
		this.gachaManager = new GachaManager(this);
		this.shopManager = new ShopManager(this);
		this.multiplayerManager = new MultiplayerManager(this);
		this.dungeonManager = new DungeonManager(this);
		
		// Ticker
		this.gameLoop = new Timer();
		this.gameLoop.scheduleAtFixedRate(new TimerTask() {
			@Override
			public void run() {
				try {
					onTick();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}, new Date(), 1000L);
		
		// Shutdown hook
		Runtime.getRuntime().addShutdownHook(new Thread(this::onServerShutdown));
	}
	
	public GameServerPacketHandler getPacketHandler() {
		return packetHandler;
	}

	public Map<Integer, GenshinPlayer> getPlayers() {
		return players;
	}

	public ChatManager getChatManager() {
		return chatManager;
	}

	public InventoryManager getInventoryManager() {
		return inventoryManager;
	}

	public GachaManager getGachaManager() {
		return gachaManager;
	}
	
	public ShopManager getShopManager() {
		return shopManager;
	}

	public MultiplayerManager getMultiplayerManager() {
		return multiplayerManager;
	}
	
	public DungeonManager getDungeonManager() {
		return dungeonManager;
	}
	
	public void registerPlayer(GenshinPlayer player) {
		getPlayers().put(player.getId(), player);
	}

	public GenshinPlayer getPlayerById(int id) {
		return this.getPlayers().get(id);
	}
	
	public GenshinPlayer forceGetPlayerById(int id) {
		// Console check
		if (id == GenshinConstants.SERVER_CONSOLE_UID) {
			return null;
		}
		
		// Get from online players
		GenshinPlayer player = this.getPlayerById(id);
		
		// Check database if character isnt here
		if (player == null) {
			player = DatabaseHelper.getPlayerById(id);
		}
		
		return player;
	}
	
	public SocialDetail.Builder getSocialDetailById(int id) {
		// Get from online players
		GenshinPlayer player = this.forceGetPlayerById(id);
	
		if (player == null) {
			return null;
		}
		
		return player.getSocialDetail();
	}
	
	public void onTick() throws Exception {
		for (GenshinPlayer player : this.getPlayers().values()) {
			player.onTick();
		}
	}

	@Override
	public void onStartFinish() {
		Grasscutter.getLogger().info("Game Server started on port " + address.getPort());
	}
	
	public void onServerShutdown() {
		// Kick and save all players
		List<GenshinPlayer> list = new ArrayList<>(this.getPlayers().size());
		list.addAll(this.getPlayers().values());
		
		for (GenshinPlayer player : list) {
			player.getSession().close();
		}
	}
}