source: network-game/common/MessageProcessor.cpp@ 373089e

Last change on this file since 373089e 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
RevLine 
[1a3c42d]1#include "MessageProcessor.h"
2
[5a64bea]3#include <iostream>
[d05086b]4#include <fstream>
[5a64bea]5
6MessageProcessor::MessageProcessor() {
7 lastUsedId = 0;
8}
9
10MessageProcessor::~MessageProcessor() {
11}
12
[d05086b]13int MessageProcessor::sendMessage(NETWORK_MSG *msg, int sock, struct sockaddr_in *dest, ofstream* outputLog) {
[46d6469]14 cout << "Sending message of type " << msg->type << endl;
15
[9b5d30b]16 msg->id = ++lastUsedId;
[5a64bea]17 MessageContainer message(*msg, *dest);
[d05086b]18
19 if (outputLog)
20 (*outputLog) << "Sending message (id " << msg->id << ") of type " << MessageContainer::getMsgTypeString(msg->type) << endl;
[5a64bea]21
[46d6469]22 sentMessages[msg->id][dest->sin_addr.s_addr] = message;
[bd2502a]23
[5a64bea]24 int ret = sendto(sock, (char*)msg, sizeof(NETWORK_MSG), 0, (struct sockaddr *)dest, sizeof(struct sockaddr_in));
25
26 return ret;
[1a3c42d]27}
28
[d05086b]29int MessageProcessor::receiveMessage(NETWORK_MSG *msg, int sock, struct sockaddr_in *source, ofstream* outputLog) {
[5a64bea]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
[6b641af]35 if (ret == -1)
36 return ret;
37
[5a64bea]38 // add id to the NETWORK_MSG struct
39 if (msg->type == MSG_TYPE_ACK) {
[46d6469]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());
[d05086b]43 if (outputLog)
44 (*outputLog) << "Received ack for message id " << msg->id << endl;
[6b641af]45 }
[198cf2d]46
47 return -1; // don't do any further processing
[5a64bea]48 }else {
[bace57b]49 bool isDuplicate = false;
[f9cb9fb]50 map<unsigned int, unsigned long long>& ackedPlayerMessages = ackedMessages[source->sin_addr.s_addr];
[bace57b]51
[f9cb9fb]52 if (ackedPlayerMessages.find(msg->id) != ackedPlayerMessages.end()) {
[bace57b]53 isDuplicate = true;
[934ab53]54 cout << "Got duplicate of type " << msg->type << endl;
[f9cb9fb]55 if (outputLog)
56 (*outputLog) << "Received duplicate (id " << msg->id << ") of type " << MessageContainer::getMsgTypeString(msg->type) << endl;
[d05086b]57 }else {
[934ab53]58 cout << "Got message of type " << msg->type << endl;
[d05086b]59 if (outputLog)
60 (*outputLog) << "Received message (id " << msg->id << ") of type " << MessageContainer::getMsgTypeString(msg->type) << endl;
61 }
[bace57b]62
[f9cb9fb]63 ackedPlayerMessages[msg->id] = getCurrentMillis();
[855f153]64
[bace57b]65 NETWORK_MSG ack;
66 ack.id = msg->id;
67 ack.type = MSG_TYPE_ACK;
[bd2502a]68
[bace57b]69 sendto(sock, (char*)&ack, sizeof(NETWORK_MSG), 0, (struct sockaddr *)source, sizeof(struct sockaddr_in));
[5a64bea]70
[bace57b]71 if (isDuplicate)
[3794f6d]72 return -1;
[5a64bea]73 }
74
75 return ret;
[1a3c42d]76}
77
[d05086b]78void MessageProcessor::resendUnackedMessages(int sock, ofstream* outputLog) {
[b35b2b2]79 map<unsigned int, map<unsigned long, MessageContainer> >::iterator it;
[bace57b]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++) {
[46d6469]86 if (!(it2->second.getAcked())) {
[9fe1807]87 sendto(sock, (const char*)it2->second.getMessage(), sizeof(NETWORK_MSG), 0, (struct sockaddr *)&it2->first, sizeof(struct sockaddr_in));
[46d6469]88 }
[bace57b]89 }
[5a64bea]90 }
[1a3c42d]91}
92
[d05086b]93void MessageProcessor::cleanAckedMessages(ofstream* outputLog) {
[b35b2b2]94 map<unsigned int, map<unsigned long, MessageContainer> >::iterator it = sentMessages.begin();
[bace57b]95 map<unsigned long, MessageContainer>::iterator it2;
[198cf2d]96
[af713bc]97 while (it != sentMessages.end()) {
[bace57b]98 it2 = it->second.begin();
[46d6469]99 while (it2 != it->second.end()) {
100 if (it2->second.getAcked()) {
[d05086b]101 if ((getCurrentMillis() - it2->second.getTimeAcked()) > 1000) {
102 if (outputLog)
103 (*outputLog) << "Removing id " << it2->second.getMessage()->id << " from the acked record" << endl;
[bace57b]104 it->second.erase(it2++);
[d05086b]105 }else
[bace57b]106 it2++;
[6b641af]107 }else
[bace57b]108 it2++;
109 }
110
111 if (it->second.size() == 0)
112 sentMessages.erase(it++);
113 else
[af713bc]114 it++;
[198cf2d]115 }
[4dbac87]116
[f9cb9fb]117 map<unsigned long, map<unsigned int, unsigned long long> >::iterator it3 = ackedMessages.begin();
118 map<unsigned int, unsigned long long>::iterator it4;
[4dbac87]119
[f9cb9fb]120 // somehow want to delete the inner map once that player logs out
[bace57b]121 while (it3 != ackedMessages.end()) {
[f9cb9fb]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++;
[4dbac87]130 }
[b35b2b2]131}
132
133map<unsigned int, map<unsigned long, MessageContainer> >& MessageProcessor::getSentMessages() {
134 return this->sentMessages;
135}
136
[f9cb9fb]137map<unsigned long, map<unsigned int, unsigned long long> >& MessageProcessor::getAckedMessages() {
[b35b2b2]138 return this->ackedMessages;
[1a3c42d]139}
Note: See TracBrowser for help on using the repository browser.