Mana
Loading...
Searching...
No Matches
network.cpp
Go to the documentation of this file.
1/*
2 * The Mana Client
3 * Copyright (C) 2004-2009 The Mana World Development Team
4 * Copyright (C) 2009-2012 The Mana Developers
5 *
6 * This file is part of The Mana Client.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
23
24#include "log.h"
25
30
31#include <enet/enet.h>
32
33#include <map>
34
38namespace {
39 ENetHost *client;
40}
41
42namespace ManaServ
43{
44
45static std::map<unsigned short, MessageHandler *> mMessageHandlers;
46
48{
49 if (enet_initialize())
50 {
51 Log::critical("Failed to initialize ENet.");
52 }
53
54 client = enet_host_create(nullptr, 3, 0, 0, 0);
55
56 if (!client)
57 {
58 Log::critical("Failed to create the local host.");
59 }
60}
61
63{
64 if (!client)
65 return; // Wasn't initialized at all
66
67 if (connections)
68 {
69 Log::critical("Tried to shutdown the network subsystem while there "
70 "are network connections left!");
71 }
72
74 enet_deinitialize();
75}
76
78{
79 if (!client)
80 {
81 Log::critical("Tried to instantiate a network object before "
82 "initializing the network subsystem!");
83 }
84
85 return new Connection(client);
86}
87
89{
90 for (const uint16_t *i = handler->handledMessages; *i; i++)
91 mMessageHandlers[*i] = handler;
92}
93
95{
96 for (const uint16_t *i = handler->handledMessages; *i; i++)
97 mMessageHandlers.erase(*i);
98}
99
101{
102 mMessageHandlers.clear();
103}
104
105
110namespace
111{
112 void dispatchMessage(ENetPacket *packet)
113 {
114 MessageIn msg((const char *)packet->data, packet->dataLength);
115
116 auto iter = mMessageHandlers.find(msg.getId());
117
118 if (iter != mMessageHandlers.end())
119 {
120 //Log::info("Received packet %x (%i B)",
121 // msg.getId(), msg.getLength());
122 iter->second->handleMessage(msg);
123 }
124 else
125 {
126 Log::info("Unhandled packet %x (%i B)",
127 msg.getId(), msg.getLength());
128 }
129
130 // Clean up the packet now that we're done using it.
131 enet_packet_destroy(packet);
132 }
133}
134
135void flush()
136{
137 ENetEvent event;
138
139 // Check if there are any new events
140 while (enet_host_service(client, &event, 0) > 0)
141 {
142 switch (event.type)
143 {
144 case ENET_EVENT_TYPE_CONNECT:
145 Log::info("Connected to port %d.", event.peer->address.port);
146 // Store any relevant server information here.
147 event.peer->data = nullptr;
148 break;
149
150 case ENET_EVENT_TYPE_RECEIVE:
151 dispatchMessage(event.packet);
152 break;
153
154 case ENET_EVENT_TYPE_DISCONNECT:
155 Log::info("Disconnected.");
156 // Reset the server information.
157 event.peer->data = nullptr;
158 break;
159
160 case ENET_EVENT_TYPE_NONE:
161 default:
162 break;
163 }
164 }
165}
166
167}
const uint16_t * handledMessages
void info(const char *log_text,...) LOG_PRINTF_ATTR
void clearNetworkHandlers()
Clears all registered message handlers.
Definition network.cpp:100
int connections
Definition internal.cpp:26
Connection * getConnection()
Returns a new Connection object.
Definition network.cpp:77
void flush()
Definition network.cpp:135
void initialize()
Initializes the network subsystem.
Definition network.cpp:47
void registerHandler(MessageHandler *handler)
Registers a message handler.
Definition network.cpp:88
void finalize()
Finalizes the network subsystem.
Definition network.cpp:62
void unregisterHandler(MessageHandler *handler)
Unregisters a message handler.
Definition network.cpp:94