void CGNetUpdater::UpdateGame(IGame *p, bool bSuccess)
{
	try
	{
		if(bSuccess)
		{
#ifndef _DEBUG
			BSTR _bstr;
			if(SUCCEEDED(p->get_Name(&_bstr) || _bstr_t(_bstr) == _bstr_t("Falcon4")))
#endif
			{
				p->AddRef();
				m_arrGames.push_back(p);

				if(FilterGame(p))
				{
					MakeServerItem(m_pListServers, p);

					m_pListServers->ReorderBranch(m_pListServers->GetRoot());
					m_pListServers->RecalcSize();
					m_pListServers->Parent_->RefreshClient(m_pListServers->GetClient());
				}
			}
		}

		m_nUpdatedServers++;
		UpdateServerStatus();
	}

	catch(_com_error e)
	{
		MonoPrint("CGNetUpdater::Refresh - _com_error 0x%X", e.Error());
	}
}
void CServerContext::HandleNetClientAuth( SNetSocket_t clientSocket, NetClientAuth_t *pClientAuth )
{
	if( clientSocketMap.find( clientSocket ) != clientSocketMap.end() )
	{
		return;
	}

	if ( numClients >= MAX_CLIENTS )
	{
		NetServerConnectionDenied_t denyMsg;
		denyMsg.denyReason = EDenyServerFull;

		networking->SendDataOnSocket( clientSocket, (void *)&denyMsg, sizeof( denyMsg ), true );
		return;
	}

	uint32 clientIP;
	networking->GetSocketInfo( clientSocket, NULL, NULL, &clientIP, NULL );

	CSteamID clientSteamID;
	EConnectionDenyReason denyReason = EDenyAuthFailed;
	bool passedAuth = gameserver->SendUserConnectAndAuthenticate( clientIP, pClientAuth->authTicket, pClientAuth->ticketLen, &clientSteamID );

	if( clientSteamMap.find( clientSteamID ) != clientSteamMap.end() )
	{
		passedAuth = false;
		denyReason = EDenySteamIDExists;
	}

	if ( !passedAuth )
	{
		NetServerConnectionDenied_t denyMsg;
		denyMsg.denyReason = denyReason;

		networking->SendDataOnSocket( clientSocket, (void *)&denyMsg, sizeof( denyMsg ), true );

		return;
	}

	CUser *user = new CUser(clientSocket, clientSteamID, pClientAuth->username);

	clientSocketMap.insert( SocketUserMap::value_type( clientSocket, user ) );
	clientSteamMap.insert( SteamUserMap::value_type( user->GetSteamID(), user ) );
	numClients++;

	UpdateServerStatus();

	std::cout << "[SERVER] " << *user << " connected. Clients: " << numClients << ", Max Clients: " << MAX_CLIENTS << std::endl;

	NetServerClientAuthed_t authedMsg;
	strcpy( authedMsg.messageOfTheDay, "Welcome to the idler2 test server. Please report any bugs and issues to: VoiDeD @ irc.gamesurge.net / #opensteamworks" );

	networking->SendDataOnSocket( clientSocket, (void *)&authedMsg, sizeof( authedMsg ), true );
}
bool CServerContext::HandleCallback(const CallbackMsg_t &callback)
{
	switch(callback.m_iCallback)
	{
		case SteamServersConnected_t::k_iCallback:
			std::cout << "[SERVER] Connected to steam back-end." << std::endl;
			UpdateServerStatus();
			break;

		case SocketStatusCallback_t::k_iCallback:
			HandleCallbackSocketStatus( (SocketStatusCallback_t *)callback.m_pubParam );
			break;

		case GSPolicyResponse_t::k_iCallback:
			HandleCallbackPolicyResponse( (GSPolicyResponse_t *)callback.m_pubParam );
			break;

		case GSClientKick_t::k_iCallback:
			HandleCallbackClientKick( (GSClientKick_t *)callback.m_pubParam );
			break;

		case GSClientDeny_t::k_iCallback:
			HandleCallbackClientDeny( (GSClientDeny_t *)callback.m_pubParam );
			break;

		case GSClientApprove_t::k_iCallback:
			HandleCallbackClientApprove( (GSClientApprove_t *)callback.m_pubParam );
			break;

		case GSItemCount_t::k_iCallback:
			HandleCallbackItemCount( (GSItemCount_t *)callback.m_pubParam );
			break;

		case SteamAPICallCompleted_t::k_iCallback:
			break;

		default:
			return false;
	}
	return true;
}
DWORD WINAPI Server()
{
	SOCKET sock;
	DWORD ThreadID;

	SYSTEM_INFO system_info;

	struct sockaddr_in addr;
	int iSize = sizeof(sockaddr_in);

	server_sock = CreateSocket(LampServerPort, LampServerIpAddress);
	if (server_sock == INVALID_SOCKET || server_sock == SOCKET_ERROR)
	{
		MessageBox(NULL, L"端口被占用", L"Error", MB_OK);
		beRunning = FALSE;
		UpdateServerStatus();
		return false;
	}
	beRunning = true;
	UpdateServerStatus();
	
	//创建完成端口句柄
	completionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, null, 0, 0);

	//创建工作者线程
	GetSystemInfo(&system_info);
	for (UINT i = 0; i < system_info.dwNumberOfProcessors; ++i)
	{
		HANDLE ThreadHandle;
		ThreadHandle = CreateThread(null, 0, LampWorkerThread, completionPort, 0, &ThreadID);
		CloseHandle(ThreadHandle);
	}

	HANDLE hSendLampDataToPCThread = ::CreateThread(0, 0, (LPTHREAD_START_ROUTINE)LampThread, NULL, 0, &ThreadID);
	if (hSendLampDataToPCThread != 0)
	{
		CloseHandle(hSendLampDataToPCThread);
		//MessageBox(NULL, L"SendLampDataToPCThread启动成功", L"Error", MB_OK);
	}
	char buf[40] = {0x00};

	while(server_sock != INVALID_SOCKET && beRunning)
	{
		sock = ::accept(server_sock, (sockaddr *)&addr, &iSize);
		if (sock == INVALID_SOCKET)
		{
			continue;
		}

		//设置socket为非阻塞模式
		//int iMode = 1;
		//ioctlsocket(sock, FIONBIO, (u_long FAR*) &iMode);

		fd_set fd;
		struct timeval time_out;
		FD_ZERO(&fd);
		FD_SET(sock, &fd);
		time_out.tv_sec = 20;	//设置超时时间为20s
		time_out.tv_usec = 0;

		//对于每个新的lamp连接,等待20s接受其发送的消息,若没有收到则关闭连接
		int err = select(0, &fd, NULL, NULL, &time_out);
		if ((err == SOCKET_ERROR) || (err == 0))
		{
			closemysocket(sock);
			continue;
		}

		if (FD_ISSET(sock, &fd))
		{
			//接收标记,区分连接是客户端还是节点
			char label[1] = {0x00};
			if (Recvn(sock, label, sizeof(label)) < sizeof(label))
			{
				closemysocket(sock);
				continue;
			}

			if ((u_char)label[0] == 0xAA)	//客户端连接
			{
				GUID guid;
				if (S_OK != ::CoCreateGuid(&guid))	//为每个pc端生成唯一id
				{
					closemysocket(sock);
					continue;
				}

				PCClient *pc = new PCClient(sock, guid, addr);
				{
					MutexGuard guard(PCClientListMutex);
					PCClientList.push_back(pc);
				}
				UpdatePCListView();

				HANDLE hThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)PCClientThread, (void *)pc, 0, &ThreadID);
				if (hThread != 0)
				{
					CloseHandle(hThread);//MessageBox(NULL, L"PC连接成功", L"Error", MB_OK);
				}
			}
			else if (label[0] == 0x5A)	//节点连接
			{
				//接收数据长度和节点ID
				char len_lampid[3] = {0x00};
				if (Recvn(sock, len_lampid, sizeof(len_lampid)) < sizeof(len_lampid))
				{
					closemysocket(sock);
					continue;
				}

				int len = len_lampid[0];
				char* data = new char[len + 1];
				data[0] = 0x5A;
				memcpy(data + 1, len_lampid, sizeof(len_lampid));

				if (Recvn(sock, data + 4, len - sizeof(len_lampid)) < (int)(len - sizeof(len_lampid)))
				{
					closemysocket(sock);
					continue;
				}

				SendDataToPCClient(data, len + 1);
				delete[] data;
				u_short lampid = *(u_short*)(len_lampid + 1);	//len_lampid[1]和len_lampid[2]表示id的低字节和高字节部分
				//检查此lampid是否已经存在列表中
				if (citylamp.QueryLampID(lampid))
				{
					closemysocket(sock);
					continue;
				}

				LPLampMutexSockStruct lpLMSS = new LampMutexSockStruct(sock, &addr, lampid, RECV_POSTED);
				citylamp.SetLampID2LampMutexSockMap(lampid, lpLMSS);
				UpdateLampListView(true, lampid);

				//将lampsock绑定到完成端口
				/*
				LPPER_HANDLE_DATA lpPerHandleData = (LPPER_HANDLE_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PER_HANDLE_DATA));
				lpPerHandleData->Socket = sock;
				memcpy(&lpPerHandleData->ClientAddr, &addr, sizeof(sockaddr_in));
				lpPerHandleData->LampID = lampid;
				CreateIoCompletionPort((HANDLE)sock, completionPort, (DWORD)lpPerHandleData, 0);
				*/
				CreateIoCompletionPort((HANDLE)sock, completionPort, (DWORD)lpLMSS->lpPerHandleData, 0);

				/*
				LPPER_IO_DATA lpPerIOData = (LPPER_IO_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PER_IO_DATA));
				lpPerIOData->Buffer.len = MAXBUFSIZE;
				lpPerIOData->Buffer.buf = lpPerIOData->szMessage;
				lpPerIOData->OperationType = RECV_POSTED;
				WSARecv(lpPerHandleData->Socket, &lpPerIOData->Buffer, 1, &lpPerIOData->NumberOfBytesTransferred, &lpPerIOData->Flags, &lpPerIOData->Overlapped, null);
				*/
				WSARecv(lpLMSS->lpPerHandleData->Socket, &lpLMSS->lpPerIOData->Buffer, 1, &lpLMSS->lpPerIOData->NumberOfBytesTransferred, &lpLMSS->lpPerIOData->Flags, &lpLMSS->lpPerIOData->Overlapped, null);
				//MessageBox(NULL, L"Lamp连接成功", L"Error", MB_OK);
			}
			else
			{
				closemysocket(sock);
				continue;
			}
		}
	}

	closemysocket(server_sock);
	WSACleanup();
	UpdateServerStatus();
	beRunning = FALSE;
	return 1;
}
void HookupServerBrowserControls(long ID)
{
	C_Window *winme;
	C_Button *ctrl;
	C_TreeList *tree;

	char strVersion[0x20];
	sprintf(strVersion,"%1d.%02d.%1d.%5d",MajorVersion, MinorVersion, gLangIDNum, BuildNumber);

	
	winme=gMainHandler->FindWindow(JETNET_WIN);

	if(winme == NULL)
		return;

	m_pWnd = winme;
	m_pWnd->SetKBCallback(MainKBCallback);

	ctrl = (C_Button *) winme->FindControl(CLOSE_WINDOW);
	if(ctrl)
		ctrl->SetCallback(LocalCloseWindowCB);

	tree=(C_TreeList*)winme->FindControl(JETNET_SERVER_TREE);
	if(tree)
	{
		m_pListServers=tree;
		m_pListServers->SetDelCallback(OnDeleteItemServerList);
		m_pListServers->SetSortType(TREE_SORT_CALLBACK);
		m_pListServers->SetSortCallback(ServerListSortCB_Ping);
	}

	ctrl = (C_Button *) winme->FindControl(JETNET_BROWSER_BACK);
	if(ctrl)
		ctrl->SetCallback(OnClickedBack);

	ctrl = (C_Button *) winme->FindControl(JETNET_BROWSER_REFRESH);
	if(ctrl)
		ctrl->SetCallback(OnClickedRefresh);

	ctrl = (C_Button *) winme->FindControl(JETNET_BROWSER_PLAY);
	if(ctrl)
		ctrl->SetCallback(OnClickedPlay);

	ctrl = (C_Button *) winme->FindControl(JETNET_BROWSER_FILTER_ALL);
	if(ctrl)
		ctrl->SetCallback(OnClickedFilter_All);

	ctrl = (C_Button *) winme->FindControl(JETNET_BROWSER_FILTER_CAMPAIGN);
	if(ctrl)
		ctrl->SetCallback(OnClickedFilter_Campaign);

	ctrl = (C_Button *) winme->FindControl(JETNET_BROWSER_FILTER_TE);
	if(ctrl)
		ctrl->SetCallback(OnClickedFilter_TE);

	ctrl = (C_Button *) winme->FindControl(JETNET_BROWSER_FILTER_DOGFIGHT);
	if(ctrl)
		ctrl->SetCallback(OnClickedFilter_Dogfight);

	ctrl = (C_Button *) winme->FindControl(JETNET_BROWSER_FILTER_FAVORITES);
	if(ctrl)
		ctrl->SetCallback(OnClickedFilter_Favorites);

	ctrl = (C_Button *) winme->FindControl(JETNET_BROWSER_FILTER_POPULATED);
	if(ctrl)
		ctrl->SetCallback(OnClickedFilter_Populated);

	ctrl = (C_Button *) winme->FindControl(JETNET_SORT_SERVERNAME);
	if(ctrl)
		ctrl->SetCallback(OnClickedSort_ServerName);

	ctrl = (C_Button *) winme->FindControl(JETNET_SORT_PING);
	if(ctrl)
		ctrl->SetCallback(OnClickedSort_Ping);

	ctrl = (C_Button *) winme->FindControl(JETNET_SORT_MODE);
	if(ctrl)
		ctrl->SetCallback(OnClickedSort_Mode);

	ctrl = (C_Button *) winme->FindControl(JETNET_SORT_PLAYERS);
	if(ctrl)
		ctrl->SetCallback(OnClickedSort_Players);

	ctrl = (C_Button *) winme->FindControl(JETNET_SORT_LOCATION);
	if(ctrl)
		ctrl->SetCallback(OnClickedSort_Location);

/*	ctrl = (C_Button *) winme->FindControl(SETUP_JETNET_ENABLEUPLINK);
	if(ctrl)
		ctrl->SetCallback(OnClickedSettings);
*/
	m_pWndStatus = (C_Text *) winme->FindControl(JETNET_STATUS);

	m_hEventShutdown = CreateEvent(NULL, FALSE, FALSE, NULL);

	UpdateServerStatus();

//	SetJNSettings();	// setup window
}
bool CServerContext::Begin()
{
	std::cout << "[SERVER] Loading item DB... ";

	if( !CItemDB::LoadDB() )
		return false;

	std::cout << "Loaded." << std::endl << "[SERVER] Initializing... ";

	pipe = client->CreateSteamPipe();
	client->SetLocalIPBinding(bindip, serverport-100);

	user = client->CreateLocalUser(&pipe, k_EAccountTypeGameServer);
	if (!user)
	{
		std::cerr << "Steam user could not be created." << std::endl;
		return false;
	}

	masterserver = (ISteamMasterServerUpdater001 *)client->GetISteamMasterServerUpdater(user, pipe, STEAMMASTERSERVERUPDATER_INTERFACE_VERSION_001);
	if (!masterserver)
	{
		std::cerr << "Unable to get " STEAMMASTERSERVERUPDATER_INTERFACE_VERSION_001 << std::endl;
		return false;
	}

	gameserver = (ISteamGameServer009 *)client->GetISteamGameServer(user, pipe, STEAMGAMESERVER_INTERFACE_VERSION_009);
	if (!gameserver)
	{
		std::cerr << "Unable to get " STEAMGAMESERVER_INTERFACE_VERSION_009 << std::endl;
		return false;
	}

	gameserveritems = (ISteamGameServerItems004 *)client->GetISteamGenericInterface(user, pipe, STEAMGAMESERVERITEMS_INTERFACE_VERSION_004);
	if (!gameserveritems)
	{
		std::cerr << "Unable to get " STEAMGAMESERVERITEMS_INTERFACE_VERSION_004 << std::endl;
		return false;
	}

	networking = (ISteamNetworking002 *)client->GetISteamNetworking( user, pipe, STEAMNETWORKING_INTERFACE_VERSION_002 );
	if (!networking)
	{
		std::cerr << "Unable to get " STEAMNETWORKING_INTERFACE_VERSION_002 << std::endl;
		return false;
	}

	bool serverInit = gameserver->SetServerType(SERVER_FLAGS, 0, serverport, 0, serverport-1, "tf", "1.0.7.1", false);
	if (!serverInit)
	{
		std::cerr << "Error initializing SteamGameServer type." << std::endl;
		return false;
	}

	serverSocket = networking->CreateListenSocket( 0, 0, serverport, false );
	if ( !serverSocket )
	{
		std::cerr << "Unable to create listen socket." << std::endl;
		return false;
	}

	UpdateServerStatus();
	masterserver->SetActive(true);

	gameserver->LogOn();

	std::cout << "Complete. pipe: " << pipe << " user: " << user << std::endl;

	running = true;
	lastping = time(0);

	return true;
}