]> git.mxchange.org Git - flightgear.git/blob - src/MultiPlayer/multiplaytxmgr.cxx
Add includes for MacOS X
[flightgear.git] / src / MultiPlayer / multiplaytxmgr.cxx
1 // multiplaytxmgr.cxx -- routines for transmitting multiplayer data
2 //                       for Flightgear
3 //
4 // Written by Duncan McCreanor, started February 2003.
5 // duncan.mccreanor@airservicesaustralia.com
6 //
7 // Copyright (C) 2003  Airservices Australia
8 //
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License as
11 // published by the Free Software Foundation; either version 2 of the
12 // License, or (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 // General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 //
23
24 /******************************************************************
25 * $Id$
26 *
27 * Description: The multiplayer tx manager provides is used
28 * to send data to another player or a server for an
29 * interactive multiplayer FlightGear simulation.
30 *
31 ******************************************************************/
32
33 #include <sys/types.h>
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <arpa/inet.h>
37 #include <plib/netSocket.h>
38 #include <stdlib.h>
39 #include <Main/fg_props.hxx>
40 #include "multiplaytxmgr.hxx"
41 #include "mpmessages.hxx"
42 #include "mpplayer.hxx"
43
44 // These constants are provided so that the ident command can list file versions.
45 const char sMULTIPLAYTXMGR_BID[] = "$Id$";
46 const char sMULTIPLAYTXMGR_HID[] = MULTIPLAYTXMGR_HID;
47
48
49
50 /******************************************************************
51 * Name: FGMultiplayTxMgr
52 * Description: Constructor.
53 ******************************************************************/
54 FGMultiplayTxMgr::FGMultiplayTxMgr() {
55
56     int iPlayerCnt;         // Count of players in player array
57
58     // Initialise private members
59     m_bInitialised = false;
60     mLocalPlayer = NULL;
61
62 }
63
64
65 /******************************************************************
66 * Name: ~FGMultiplayTxMgr
67 * Description: Destructor. Closes and deletes objects owned by
68 * this object.
69 ******************************************************************/
70 FGMultiplayTxMgr::~FGMultiplayTxMgr() {
71
72     Close();
73
74 }
75
76
77 /******************************************************************
78 * Name: init
79 * Description: Initialises multiplayer transmit
80 ******************************************************************/
81 bool FGMultiplayTxMgr::init(void) {
82
83
84     string sTxAddress;                          // Destination address
85     int iTxPort;
86     bool bSuccess = true;                       // Result of initialisation
87
88     // Initialise object if not already done
89     if (!m_bInitialised) {
90
91         // Set members from property values
92         string sTxAddress = fgGetString("/sim/multiplay/txhost");
93         iTxPort = fgGetInt("/sim/multiplay/txport");
94
95         cout << "FGMultiplayTxMgr::init - txaddress= " << sTxAddress << endl;
96         cout << "FGMultiplayTxMgr::init - txport= " << iTxPort << endl;
97         
98         if (iTxPort > 0) {
99
100
101             // Create and open tx socket
102             mDataTxSocket = new netSocket();
103             if (!mDataTxSocket->open(false)) {
104                 // Failed to open tx socket
105                 cerr << "FGMultiplayTxMgr::init - Failed to create data transmit socket" << endl;
106                 bSuccess = false;
107             } else {
108                 mDataTxSocket->setBroadcast(true);
109                 if (mDataTxSocket->connect(sTxAddress.c_str(), iTxPort) != 0) {
110                     // Failed to connect tx socket
111                     cerr << "FGMultiplayTxMgr::init - Failed to connect data transmit socket" << endl;
112                     bSuccess = false;
113                 }
114             }
115
116             // Create a player object for the local player
117             if (bSuccess) {
118                 mLocalPlayer = new MPPlayer();
119                 if (!mLocalPlayer->Open(fgGetString("/sim/multiplay/rxaddress"), fgGetInt("/sim/multiplay/rxport"),
120                                         fgGetString("/sim/multiplay/callsign"), fgGetString("/sim/model/path"), true)) {
121                     cerr << "FGMultiplayTxMgr::init - Failed to create player object for local player" << endl;
122                     bSuccess = false;
123                 }
124             }
125
126         // If Tx port == zero then don't initialise
127         } else {
128
129             cout << "FGMultiplayTxMgr::init - Tx Port is zero. Multiplay out disabled." << endl;
130             bSuccess = false;
131
132         }
133
134         // Save manager state
135         m_bInitialised = bSuccess;
136
137     } else {
138         cerr << "FGMultiplayTxMgr::init - Attempt to init object that is already opened" << endl;
139         bSuccess = false;
140     }
141
142
143     /* Return true if init succeeds */
144     return bSuccess;
145
146 }
147
148
149 /******************************************************************
150 * Name: Close
151 * Description: Closes and deletes the local player object. Closes
152 * and deletes the tx socket. Resets the object state to unitialised.
153 ******************************************************************/
154 void FGMultiplayTxMgr::Close(void) {
155
156
157     // Delete local player
158     if (mLocalPlayer) {
159         delete mLocalPlayer;
160         mLocalPlayer = NULL;
161     }
162
163     // Delete socket
164     if (mDataTxSocket) {
165         mDataTxSocket->close();
166         delete mDataTxSocket;
167         mDataTxSocket = NULL;
168     }
169
170     m_bInitialised = false;
171
172 }
173
174
175 /******************************************************************
176 * Name: SendMyPosition
177 * Description: Sends the position data for the local position.
178 ******************************************************************/
179 void FGMultiplayTxMgr::SendMyPosition(const sgMat4 PlayerPosMat4) {
180
181     T_MsgHdr MsgHdr;
182     T_PositionMsg PosMsg;
183     char sMsg[sizeof(T_MsgHdr) + sizeof(T_PositionMsg)];
184
185     if (m_bInitialised) {
186         mLocalPlayer->SetPosition(PlayerPosMat4);
187         mLocalPlayer->FillPosMsg(&MsgHdr, &PosMsg);
188         memcpy(sMsg, &MsgHdr, sizeof(T_MsgHdr));
189         memcpy(sMsg + sizeof(T_MsgHdr), &PosMsg, sizeof(T_PositionMsg));
190         mDataTxSocket->send(sMsg, sizeof(T_MsgHdr) + sizeof(T_PositionMsg), 0);
191     }
192
193
194 }
195
196
197
198 /******************************************************************
199 * Name: SendTextMessage
200 * Description: Sends a message to the player. The message must
201 * contain a valid and correctly filled out header and optional
202 * message body.
203 ******************************************************************/
204 void FGMultiplayTxMgr::SendTextMessage(const string &sMsgText) const {
205
206     bool bResult = false;
207     T_MsgHdr MsgHdr;
208     T_ChatMsg ChatMsg;
209     int iNextBlockPosition = 0;
210     char sMsg[sizeof(T_MsgHdr) + sizeof(T_ChatMsg)];
211
212     if (m_bInitialised) {
213
214         mLocalPlayer->FillMsgHdr(&MsgHdr, CHAT_MSG_ID);
215
216         // Divide the text string into blocks that fit in the message
217         // and send the blocks.
218         while (iNextBlockPosition < sMsgText.length()) {
219             strncpy(ChatMsg.sText, sMsgText.substr(iNextBlockPosition, MAX_CHAT_MSG_LEN - 1).c_str(), MAX_CHAT_MSG_LEN);
220             ChatMsg.sText[MAX_CHAT_MSG_LEN - 1] = '\0';
221             memcpy(sMsg, &MsgHdr, sizeof(T_MsgHdr));
222             memcpy(sMsg + sizeof(T_MsgHdr), &ChatMsg, sizeof(T_ChatMsg));
223             mDataTxSocket->send(sMsg, sizeof(T_MsgHdr) + sizeof(T_ChatMsg), 0);
224             iNextBlockPosition += MAX_CHAT_MSG_LEN - 1;
225         }
226
227     }
228
229 }
230