]> git.mxchange.org Git - flightgear.git/blob - src/MultiPlayer/multiplaytxmgr.cxx
Change cout and cerr in SG_LOG() where appropriate, otherwise comment it out
[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
40 #include <simgear/debug/logstream.hxx>
41 #include <Main/fg_props.hxx>
42
43 #include "multiplaytxmgr.hxx"
44 #include "mpmessages.hxx"
45 #include "mpplayer.hxx"
46
47 // These constants are provided so that the ident command can list file versions.
48 const char sMULTIPLAYTXMGR_BID[] = "$Id$";
49 const char sMULTIPLAYTXMGR_HID[] = MULTIPLAYTXMGR_HID;
50
51
52
53 /******************************************************************
54 * Name: FGMultiplayTxMgr
55 * Description: Constructor.
56 ******************************************************************/
57 FGMultiplayTxMgr::FGMultiplayTxMgr() {
58
59     int iPlayerCnt;         // Count of players in player array
60
61     // Initialise private members
62     m_bInitialised = false;
63     mLocalPlayer = NULL;
64
65 }
66
67
68 /******************************************************************
69 * Name: ~FGMultiplayTxMgr
70 * Description: Destructor. Closes and deletes objects owned by
71 * this object.
72 ******************************************************************/
73 FGMultiplayTxMgr::~FGMultiplayTxMgr() {
74
75     Close();
76
77 }
78
79
80 /******************************************************************
81 * Name: init
82 * Description: Initialises multiplayer transmit
83 ******************************************************************/
84 bool FGMultiplayTxMgr::init(void) {
85
86
87     string sTxAddress;                          // Destination address
88     int iTxPort;
89     bool bSuccess = true;                       // Result of initialisation
90
91     // Initialise object if not already done
92     if (!m_bInitialised) {
93
94         // Set members from property values
95         string sTxAddress = fgGetString("/sim/multiplay/txhost");
96         iTxPort = fgGetInt("/sim/multiplay/txport");
97
98         SG_LOG( SG_NETWORK, SG_INFO, "FGMultiplayTxMgr::init - txaddress= "
99                                      << sTxAddress );
100         SG_LOG( SG_NETWORK, SG_INFO, "FGMultiplayTxMgr::init - txport= "
101                                      << iTxPort );
102         
103         if (iTxPort > 0) {
104
105
106             // Create and open tx socket
107             mDataTxSocket = new netSocket();
108             if (!mDataTxSocket->open(false)) {
109                 // Failed to open tx socket
110                 cerr << "FGMultiplayTxMgr::init - Failed to create data transmit socket" << endl;
111                 bSuccess = false;
112             } else {
113                 mDataTxSocket->setBroadcast(true);
114                 if (mDataTxSocket->connect(sTxAddress.c_str(), iTxPort) != 0) {
115                     // Failed to connect tx socket
116                     cerr << "FGMultiplayTxMgr::init - Failed to connect data transmit socket" << endl;
117                     bSuccess = false;
118                 }
119             }
120
121             // Create a player object for the local player
122             if (bSuccess) {
123                 mLocalPlayer = new MPPlayer();
124                 if (!mLocalPlayer->Open(fgGetString("/sim/multiplay/rxaddress"), fgGetInt("/sim/multiplay/rxport"),
125                                         fgGetString("/sim/multiplay/callsign"), fgGetString("/sim/model/path"), true)) {
126                     cerr << "FGMultiplayTxMgr::init - Failed to create player object for local player" << endl;
127                     bSuccess = false;
128                 }
129             }
130
131         // If Tx port == zero then don't initialise
132         } else {
133
134             SG_LOG( SG_NETWORK, SG_WARN, "FGMultiplayTxMgr::init - Tx Port is zero. Multiplay out disabled." );
135             bSuccess = false;
136
137         }
138
139         // Save manager state
140         m_bInitialised = bSuccess;
141
142     } else {
143         SG_LOG( SG_NETWORK, SG_ALERT, "FGMultiplayTxMgr::init - Attempt to init object that is already opened" );
144         bSuccess = false;
145     }
146
147
148     /* Return true if init succeeds */
149     return bSuccess;
150
151 }
152
153
154 /******************************************************************
155 * Name: Close
156 * Description: Closes and deletes the local player object. Closes
157 * and deletes the tx socket. Resets the object state to unitialised.
158 ******************************************************************/
159 void FGMultiplayTxMgr::Close(void) {
160
161
162     // Delete local player
163     if (mLocalPlayer) {
164         delete mLocalPlayer;
165         mLocalPlayer = NULL;
166     }
167
168     // Delete socket
169     if (mDataTxSocket) {
170         mDataTxSocket->close();
171         delete mDataTxSocket;
172         mDataTxSocket = NULL;
173     }
174
175     m_bInitialised = false;
176
177 }
178
179
180 /******************************************************************
181 * Name: SendMyPosition
182 * Description: Sends the position data for the local position.
183 ******************************************************************/
184 void FGMultiplayTxMgr::SendMyPosition(const sgMat4 PlayerPosMat4) {
185
186     T_MsgHdr MsgHdr;
187     T_PositionMsg PosMsg;
188     char sMsg[sizeof(T_MsgHdr) + sizeof(T_PositionMsg)];
189
190     if (m_bInitialised) {
191         mLocalPlayer->SetPosition(PlayerPosMat4);
192         mLocalPlayer->FillPosMsg(&MsgHdr, &PosMsg);
193         memcpy(sMsg, &MsgHdr, sizeof(T_MsgHdr));
194         memcpy(sMsg + sizeof(T_MsgHdr), &PosMsg, sizeof(T_PositionMsg));
195         mDataTxSocket->send(sMsg, sizeof(T_MsgHdr) + sizeof(T_PositionMsg), 0);
196     }
197
198
199 }
200
201
202
203 /******************************************************************
204 * Name: SendTextMessage
205 * Description: Sends a message to the player. The message must
206 * contain a valid and correctly filled out header and optional
207 * message body.
208 ******************************************************************/
209 void FGMultiplayTxMgr::SendTextMessage(const string &sMsgText) const {
210
211     bool bResult = false;
212     T_MsgHdr MsgHdr;
213     T_ChatMsg ChatMsg;
214     int iNextBlockPosition = 0;
215     char sMsg[sizeof(T_MsgHdr) + sizeof(T_ChatMsg)];
216
217     if (m_bInitialised) {
218
219         mLocalPlayer->FillMsgHdr(&MsgHdr, CHAT_MSG_ID);
220
221         // Divide the text string into blocks that fit in the message
222         // and send the blocks.
223         while (iNextBlockPosition < sMsgText.length()) {
224             strncpy(ChatMsg.sText, sMsgText.substr(iNextBlockPosition, MAX_CHAT_MSG_LEN - 1).c_str(), MAX_CHAT_MSG_LEN);
225             ChatMsg.sText[MAX_CHAT_MSG_LEN - 1] = '\0';
226             memcpy(sMsg, &MsgHdr, sizeof(T_MsgHdr));
227             memcpy(sMsg + sizeof(T_MsgHdr), &ChatMsg, sizeof(T_ChatMsg));
228             mDataTxSocket->send(sMsg, sizeof(T_MsgHdr) + sizeof(T_ChatMsg), 0);
229             iNextBlockPosition += MAX_CHAT_MSG_LEN - 1;
230         }
231
232     }
233
234 }
235