source: network-game/common/MessageProcessor.cpp@ 6319311

Last change on this file since 6319311 was 6319311, checked in by Dmitry Portnoy <dportnoy@…>, 11 years ago

Some redfinition issues related to winsock2 are fixed and a few allegro rendering functions are now in GameRender

  • Property mode set to 100644
File size: 4.7 KB
Line 
1#include "MessageProcessor.h"
2
3#include <iostream>
4#include <fstream>
5
6MessageProcessor::MessageProcessor() {
7 lastUsedId = 0;
8}
9
10MessageProcessor::~MessageProcessor() {
11}
12
13int MessageProcessor::sendMessage(NETWORK_MSG *msg, int sock, struct sockaddr_in *dest, ofstream* outputLog) {
14 cout << "Sending message of type " << msg->type << endl;
15
16 msg->id = ++lastUsedId;
17 MessageContainer message(*msg, *dest);
18
19 if (outputLog)
20 (*outputLog) << "Sending message (id " << msg->id << ") of type " << MessageContainer::getMsgTypeString(msg->type) << endl;
21
22 sentMessages[msg->id][dest->sin_addr.s_addr] = message;
23
24 int ret = sendto(sock, (char*)msg, sizeof(NETWORK_MSG), 0, (struct sockaddr *)dest, sizeof(struct sockaddr_in));
25
26 return ret;
27}
28
29int MessageProcessor::receiveMessage(NETWORK_MSG *msg, int sock, struct sockaddr_in *source, ofstream* outputLog) {
30 socklen_t socklen = sizeof(struct sockaddr_in);
31
32 // assume we don't care about the value of socklen
33 int ret = recvfrom(sock, (char*)msg, sizeof(NETWORK_MSG), 0, (struct sockaddr *)source, &socklen);
34
35 if (ret == -1)
36 return ret;
37
38 // add id to the NETWORK_MSG struct
39 if (msg->type == MSG_TYPE_ACK) {
40 if (!sentMessages[msg->id][source->sin_addr.s_addr].getAcked()) {
41 sentMessages[msg->id][source->sin_addr.s_addr].setAcked(true);
42 sentMessages[msg->id][source->sin_addr.s_addr].setTimeAcked(getCurrentMillis());
43 if (outputLog)
44 (*outputLog) << "Received ack for message id " << msg->id << endl;
45 }
46
47 return -1; // don't do any further processing
48 }else {
49 bool isDuplicate = false;
50 map<unsigned int, unsigned long long>& ackedPlayerMessages = ackedMessages[source->sin_addr.s_addr];
51
52 if (ackedPlayerMessages.find(msg->id) != ackedPlayerMessages.end()) {
53 isDuplicate = true;
54 cout << "Got duplicate of type " << msg->type << endl;
55 if (outputLog)
56 (*outputLog) << "Received duplicate (id " << msg->id << ") of type " << MessageContainer::getMsgTypeString(msg->type) << endl;
57 }else {
58 cout << "Got message of type " << msg->type << endl;
59 if (outputLog)
60 (*outputLog) << "Received message (id " << msg->id << ") of type " << MessageContainer::getMsgTypeString(msg->type) << endl;
61 }
62
63 ackedPlayerMessages[msg->id] = getCurrentMillis();
64
65 NETWORK_MSG ack;
66 ack.id = msg->id;
67 ack.type = MSG_TYPE_ACK;
68
69 sendto(sock, (char*)&ack, sizeof(NETWORK_MSG), 0, (struct sockaddr *)source, sizeof(struct sockaddr_in));
70
71 if (isDuplicate)
72 return -1;
73 }
74
75 return ret;
76}
77
78void MessageProcessor::resendUnackedMessages(int sock, ofstream* outputLog) {
79 map<unsigned int, map<unsigned long, MessageContainer> >::iterator it;
80 map<unsigned long, MessageContainer>::iterator it2;
81 map<unsigned long, MessageContainer> sentMsg;
82
83 for (it = sentMessages.begin(); it != sentMessages.end(); it++) {
84 sentMsg = it->second;
85 for (it2 = sentMsg.begin(); it2 != sentMsg.end(); it2++) {
86 if (!(it2->second.getAcked())) {
87 sendto(sock, (const char*)it2->second.getMessage(), sizeof(NETWORK_MSG), 0, (struct sockaddr *)&it2->first, sizeof(struct sockaddr_in));
88 }
89 }
90 }
91}
92
93void MessageProcessor::cleanAckedMessages(ofstream* outputLog) {
94 map<unsigned int, map<unsigned long, MessageContainer> >::iterator it = sentMessages.begin();
95 map<unsigned long, MessageContainer>::iterator it2;
96
97 while (it != sentMessages.end()) {
98 it2 = it->second.begin();
99 while (it2 != it->second.end()) {
100 if (it2->second.getAcked()) {
101 if ((getCurrentMillis() - it2->second.getTimeAcked()) > 1000) {
102 if (outputLog)
103 (*outputLog) << "Removing id " << it2->second.getMessage()->id << " from the acked record" << endl;
104 it->second.erase(it2++);
105 }else
106 it2++;
107 }else
108 it2++;
109 }
110
111 if (it->second.size() == 0)
112 sentMessages.erase(it++);
113 else
114 it++;
115 }
116
117 map<unsigned long, map<unsigned int, unsigned long long> >::iterator it3 = ackedMessages.begin();
118 map<unsigned int, unsigned long long>::iterator it4;
119
120 // somehow want to delete the inner map once that player logs out
121 while (it3 != ackedMessages.end()) {
122 it4 = it3->second.begin();
123 while (it4 != it3->second.end()) {
124 if ((getCurrentMillis() - it4->second) > 500)
125 it3->second.erase(it4++);
126 else
127 it4++;
128 }
129 it3++;
130 }
131}
132
133map<unsigned int, map<unsigned long, MessageContainer> >& MessageProcessor::getSentMessages() {
134 return this->sentMessages;
135}
136
137map<unsigned long, map<unsigned int, unsigned long long> >& MessageProcessor::getAckedMessages() {
138 return this->ackedMessages;
139}
Note: See TracBrowser for help on using the repository browser.