362 lines
11 KiB
C++
362 lines
11 KiB
C++
/*
|
|
* Original work: Copyright (c) 2014, Oculus VR, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* RakNet License.txt file in the licenses directory of this source tree. An additional grant
|
|
* of patent rights can be found in the RakNet Patents.txt file in the same directory.
|
|
*
|
|
*
|
|
* Modified work: Copyright (c) 2016-2017, SLikeSoft UG (haftungsbeschränkt)
|
|
*
|
|
* This source code was modified by SLikeSoft. Modifications are licensed under the MIT-style
|
|
* license found in the license.txt file in the root directory of this source tree.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "Lobby2Client_Steam.h" // If Lobby2Client_Steam.h is included before SocketLayer.h, then it will use the steam send functions
|
|
#include "Lobby2Message_Steam.h"
|
|
#include "slikenet/time.h"
|
|
#include "slikenet/sleep.h"
|
|
#include "slikenet/types.h"
|
|
#include "slikenet/peerinterface.h"
|
|
#include "slikenet/GetTime.h"
|
|
#include "slikenet/MessageIdentifiers.h"
|
|
#include <windows.h>
|
|
#include <slikenet/Kbhit.h>
|
|
#include "slikenet/Gets.h"
|
|
#include "slikenet/FullyConnectedMesh2.h"
|
|
#pragma warning( push )
|
|
#pragma warning(disable:4127) // conditional expression is constant (with Steamworks 1.23a)
|
|
#include "steam_api.h"
|
|
#pragma warning( pop )
|
|
|
|
using namespace SLNet;
|
|
|
|
Lobby2MessageFactory_Steam *messageFactory;
|
|
Lobby2Client_Steam *lobby2Client;
|
|
SLNet::RakPeerInterface *rakPeer;
|
|
SLNet::FullyConnectedMesh2 *fcm2;
|
|
uint64_t lastRoom;
|
|
|
|
void PrintCommands(void)
|
|
{
|
|
printf("a. GetRoomList\n");
|
|
printf("b. LeaveRoom\n");
|
|
printf("c. CreateRoom\n");
|
|
printf("d. JoinRoom\n");
|
|
printf("e. RefreshRoom\n");
|
|
printf("f. SendRoomChatMessage\n");
|
|
printf("g. ListRoomMembers\n");
|
|
printf("?. Help\n");
|
|
printf("(Escape). Quit\n");
|
|
}
|
|
|
|
struct SteamResults : public SLNet::Lobby2Callbacks
|
|
{
|
|
virtual void MessageResult(SLNet::Notification_Console_MemberJoinedRoom *message)
|
|
{
|
|
SLNet::Notification_Console_MemberJoinedRoom_Steam *msgSteam = (SLNet::Notification_Console_MemberJoinedRoom_Steam *) message;
|
|
SLNet::RakString msg;
|
|
msgSteam->DebugMsg(msg);
|
|
printf("%s\n", msg.C_String());
|
|
// Guy with the lower ID connects to the guy with the higher ID
|
|
uint64_t mySteamId=SteamUser()->GetSteamID().ConvertToUint64();
|
|
if (mySteamId < msgSteam->srcMemberId)
|
|
{
|
|
// Steam's NAT punch is implicit, so it takes a long time to connect. Give it extra time
|
|
unsigned int sendConnectionAttemptCount=24;
|
|
unsigned int timeBetweenSendConnectionAttemptsMS=500;
|
|
SLNET_VERIFY(rakPeer->Connect(msgSteam->remoteSystem.ToString(false), msgSteam->remoteSystem.GetPort(), 0, 0, 0, 0, sendConnectionAttemptCount, timeBetweenSendConnectionAttemptsMS) == CONNECTION_ATTEMPT_STARTED);
|
|
}
|
|
}
|
|
|
|
virtual void MessageResult(SLNet::Console_SearchRooms *message)
|
|
{
|
|
SLNet::Console_SearchRooms_Steam *msgSteam = (SLNet::Console_SearchRooms_Steam *) message;
|
|
SLNet::RakString msg;
|
|
msgSteam->DebugMsg(msg);
|
|
printf("%s\n", msg.C_String());
|
|
if (msgSteam->roomIds.GetSize()>0)
|
|
{
|
|
lastRoom=msgSteam->roomIds[0];
|
|
}
|
|
}
|
|
|
|
virtual void ExecuteDefaultResult(SLNet::Lobby2Message *message)
|
|
{
|
|
SLNet::RakString out;
|
|
message->DebugMsg(out);
|
|
printf("%s\n", out.C_String());
|
|
}
|
|
};
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
if (argc>1)
|
|
{
|
|
printf("Command arguments:\n");
|
|
for (int i=1; i < argc; i++)
|
|
{
|
|
printf("%i. %s\n", i, argv[i]);
|
|
}
|
|
}
|
|
|
|
SteamResults steamResults;
|
|
rakPeer = SLNet::RakPeerInterface::GetInstance();
|
|
fcm2 = SLNet::FullyConnectedMesh2::GetInstance();
|
|
messageFactory = new Lobby2MessageFactory_Steam;
|
|
lobby2Client = Lobby2Client_Steam::GetInstance();
|
|
lobby2Client->AddCallbackInterface(&steamResults);
|
|
lobby2Client->SetMessageFactory(messageFactory);
|
|
SocketDescriptor sd(1234,0);
|
|
rakPeer->Startup(32,&sd,1);
|
|
rakPeer->SetMaximumIncomingConnections(32);
|
|
rakPeer->AttachPlugin(fcm2);
|
|
rakPeer->AttachPlugin(lobby2Client);
|
|
// Connect manually in Notification_Console_MemberJoinedRoom
|
|
fcm2->SetConnectOnNewRemoteConnection(false, "");
|
|
SLNet::Lobby2Message* msg = messageFactory->Alloc(SLNet::L2MID_Client_Login);
|
|
lobby2Client->SendMsg(msg);
|
|
if (msg->resultCode!=L2RC_PROCESSING && msg->resultCode!=L2RC_SUCCESS)
|
|
{
|
|
printf("Steam must be running to play this game (SteamAPI_Init() failed).\n");
|
|
printf("If this fails, steam_appid.txt was probably not in the working directory.\n");
|
|
messageFactory->Dealloc(msg);
|
|
return -1;
|
|
}
|
|
messageFactory->Dealloc(msg);
|
|
|
|
PrintCommands();
|
|
|
|
bool quit=false;
|
|
char ch;
|
|
while(!quit)
|
|
{
|
|
SLNet::Packet *packet;
|
|
for (packet=rakPeer->Receive(); packet; rakPeer->DeallocatePacket(packet), packet=rakPeer->Receive())
|
|
{
|
|
switch (packet->data[0])
|
|
{
|
|
case ID_DISCONNECTION_NOTIFICATION:
|
|
// Connection lost normally
|
|
printf("ID_DISCONNECTION_NOTIFICATION\n");
|
|
break;
|
|
case ID_ALREADY_CONNECTED:
|
|
// Connection lost normally
|
|
printf("ID_ALREADY_CONNECTED\n");
|
|
break;
|
|
case ID_REMOTE_DISCONNECTION_NOTIFICATION: // Server telling the clients of another client disconnecting gracefully. You can manually broadcast this in a peer to peer enviroment if you want.
|
|
printf("ID_REMOTE_DISCONNECTION_NOTIFICATION\n");
|
|
break;
|
|
case ID_REMOTE_CONNECTION_LOST: // Server telling the clients of another client disconnecting forcefully. You can manually broadcast this in a peer to peer enviroment if you want.
|
|
printf("ID_REMOTE_CONNECTION_LOST\n");
|
|
break;
|
|
case ID_REMOTE_NEW_INCOMING_CONNECTION: // Server telling the clients of another client connecting. You can manually broadcast this in a peer to peer enviroment if you want.
|
|
printf("ID_REMOTE_NEW_INCOMING_CONNECTION\n");
|
|
break;
|
|
case ID_CONNECTION_BANNED: // Banned from this server
|
|
printf("We are banned from this server.\n");
|
|
break;
|
|
case ID_CONNECTION_ATTEMPT_FAILED:
|
|
printf("Connection attempt failed\n");
|
|
break;
|
|
case ID_NO_FREE_INCOMING_CONNECTIONS:
|
|
// Sorry, the server is full. I don't do anything here but
|
|
// A real app should tell the user
|
|
printf("ID_NO_FREE_INCOMING_CONNECTIONS\n");
|
|
break;
|
|
case ID_INVALID_PASSWORD:
|
|
printf("ID_INVALID_PASSWORD\n");
|
|
break;
|
|
|
|
case ID_CONNECTION_LOST:
|
|
// Couldn't deliver a reliable packet - i.e. the other system was abnormally
|
|
// terminated
|
|
printf("ID_CONNECTION_LOST\n");
|
|
break;
|
|
|
|
case ID_CONNECTION_REQUEST_ACCEPTED:
|
|
// This tells the client they have connected
|
|
printf("ID_CONNECTION_REQUEST_ACCEPTED to %s with GUID %s\n", packet->systemAddress.ToString(), packet->guid.ToString());
|
|
break;
|
|
|
|
case ID_NEW_INCOMING_CONNECTION:
|
|
printf("ID_NEW_INCOMING_CONNECTION\n");
|
|
break;
|
|
|
|
case ID_FCM2_NEW_HOST:
|
|
{
|
|
if (packet->systemAddress== SLNet::UNASSIGNED_SYSTEM_ADDRESS)
|
|
printf("Got new host (ourselves)");
|
|
else
|
|
printf("Got new host %s, GUID=%s", packet->systemAddress.ToString(true), packet->guid.ToString());
|
|
SLNet::BitStream bs(packet->data,packet->length,false);
|
|
bs.IgnoreBytes(1);
|
|
RakNetGUID oldHost;
|
|
bs.Read(oldHost);
|
|
// If the old host is different, then this message was due to losing connection to the host.
|
|
if (oldHost!=packet->guid)
|
|
printf(". Oldhost Guid=%s\n", oldHost.ToString());
|
|
else
|
|
printf("\n");
|
|
}
|
|
break;
|
|
|
|
default:
|
|
// It's a client, so just show the message
|
|
printf("Unknown Message ID %i\n", packet->data[0]);
|
|
break;
|
|
}
|
|
|
|
}
|
|
if (_kbhit())
|
|
{
|
|
ch=(char)_getch();
|
|
|
|
switch (ch)
|
|
{
|
|
case 'a':
|
|
{
|
|
|
|
SLNet::Lobby2Message* logoffMsg = messageFactory->Alloc(SLNet::L2MID_Console_SearchRooms);
|
|
lobby2Client->SendMsg(logoffMsg);
|
|
messageFactory->Dealloc(logoffMsg);
|
|
}
|
|
break;
|
|
|
|
case 'b':
|
|
{
|
|
if (lobby2Client->GetRoomID()==0)
|
|
{
|
|
printf("Not in a room\n");
|
|
break;
|
|
}
|
|
SLNet::Console_LeaveRoom_Steam* leaveroomMsg = (SLNet::Console_LeaveRoom_Steam*) messageFactory->Alloc(SLNet::L2MID_Console_LeaveRoom);
|
|
leaveroomMsg->roomId=lobby2Client->GetRoomID();
|
|
lobby2Client->SendMsg(leaveroomMsg);
|
|
messageFactory->Dealloc(leaveroomMsg);
|
|
}
|
|
break;
|
|
|
|
case 'c':
|
|
{
|
|
if (lobby2Client->GetRoomID()!=0)
|
|
{
|
|
printf("Already in a room\n");
|
|
break;
|
|
}
|
|
|
|
SLNet::Console_CreateRoom_Steam* createroomMsg = (SLNet::Console_CreateRoom_Steam*) messageFactory->Alloc(SLNet::L2MID_Console_CreateRoom);
|
|
// set the name of the lobby if it's ours
|
|
char rgchLobbyName[256];
|
|
createroomMsg->roomIsPublic=true;
|
|
_snprintf( rgchLobbyName, sizeof( rgchLobbyName ), "%s's lobby", SteamFriends()->GetPersonaName() );
|
|
createroomMsg->roomName=rgchLobbyName;
|
|
createroomMsg->publicSlots=8;
|
|
lobby2Client->SendMsg(createroomMsg);
|
|
messageFactory->Dealloc(createroomMsg);
|
|
|
|
}
|
|
break;
|
|
|
|
case 'd':
|
|
{
|
|
if (lobby2Client->GetRoomID()!=0)
|
|
{
|
|
printf("Already in a room\n");
|
|
break;
|
|
}
|
|
|
|
SLNet::Console_JoinRoom_Steam* joinroomMsg = (SLNet::Console_JoinRoom_Steam*) messageFactory->Alloc(SLNet::L2MID_Console_JoinRoom);
|
|
printf("Enter room id, or enter for %" PRINTF_64_BIT_MODIFIER "u: ", lastRoom);
|
|
char str[256];
|
|
Gets(str, sizeof(str));
|
|
if (str[0]==0)
|
|
{
|
|
joinroomMsg->roomId=lastRoom;
|
|
}
|
|
else
|
|
{
|
|
joinroomMsg->roomId=_atoi64(str);
|
|
}
|
|
lobby2Client->SendMsg(joinroomMsg);
|
|
messageFactory->Dealloc(joinroomMsg);
|
|
}
|
|
break;
|
|
|
|
case 'e':
|
|
{
|
|
if (lobby2Client->GetRoomID()==0)
|
|
{
|
|
printf("Not in a room\n");
|
|
break;
|
|
}
|
|
|
|
SLNet::Console_GetRoomDetails_Steam* roomdetailsMsg = (SLNet::Console_GetRoomDetails_Steam*) messageFactory->Alloc(SLNet::L2MID_Console_GetRoomDetails);
|
|
roomdetailsMsg->roomId=lobby2Client->GetRoomID();
|
|
lobby2Client->SendMsg(roomdetailsMsg);
|
|
messageFactory->Dealloc(roomdetailsMsg);
|
|
}
|
|
break;
|
|
|
|
case 'f':
|
|
{
|
|
if (lobby2Client->GetRoomID()==0)
|
|
{
|
|
printf("Not in a room\n");
|
|
break;
|
|
|
|
}
|
|
SLNet::Console_SendRoomChatMessage_Steam* roomchatMsg = (SLNet::Console_SendRoomChatMessage_Steam*) messageFactory->Alloc(SLNet::L2MID_Console_SendRoomChatMessage);
|
|
roomchatMsg->message="Test chat message.";
|
|
roomchatMsg->roomId=lobby2Client->GetRoomID();
|
|
lobby2Client->SendMsg(roomchatMsg);
|
|
messageFactory->Dealloc(roomchatMsg);
|
|
|
|
}
|
|
break;
|
|
|
|
case 'g':
|
|
{
|
|
DataStructures::OrderedList<uint64_t, uint64_t> roomMembers;
|
|
lobby2Client->GetRoomMembers(roomMembers);
|
|
for (unsigned int i=0; i < roomMembers.Size(); i++)
|
|
{
|
|
printf("%i. %s ID=%" PRINTF_64_BIT_MODIFIER "u\n", i+1, lobby2Client->GetRoomMemberName(roomMembers[i]), roomMembers[i]);
|
|
}
|
|
}
|
|
break;
|
|
|
|
|
|
case '?':
|
|
{
|
|
PrintCommands();
|
|
|
|
}
|
|
break;
|
|
|
|
case 27:
|
|
{
|
|
quit=true;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
RakSleep(30);
|
|
}
|
|
|
|
SLNet::Lobby2Message* logoffMsg = messageFactory->Alloc(SLNet::L2MID_Client_Logoff);
|
|
lobby2Client->SendMsg(logoffMsg);
|
|
messageFactory->Dealloc(logoffMsg);
|
|
rakPeer->DetachPlugin(lobby2Client);
|
|
rakPeer->DetachPlugin(fcm2);
|
|
SLNet::RakPeerInterface::DestroyInstance(rakPeer);
|
|
Lobby2Client_Steam::DestroyInstance(lobby2Client);
|
|
SLNet::FullyConnectedMesh2::DestroyInstance(fcm2);
|
|
|
|
return 1;
|
|
}
|