⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 trackerdialog.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//=========== (C) Copyright 2000 Valve, L.L.C. All rights reserved. ===========
//
// The copyright to the contents herein is the property of Valve, L.L.C.
// The contents may be used and/or copied only with the written permission of
// Valve, L.L.C., or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose: 
//=============================================================================

#include "TrackerMessageFlags.h"
#include "ServerBrowser/IServerBrowser.h"

#include "Buddy.h"
#include "DialogAuthRequest.h"
#include "DialogFindBuddy.h"
#include "DialogLoginUser.h"
#include "DialogOptions.h"
#include "DialogChat.h"
#include "DialogAbout.h"
#include "interface.h"
#include "IRunGameEngine.h"
#include "OnlineStatus.h"
#include "OnlineStatusSelectComboBox.h"
#include "PanelValveLogo.h"
#include "Tracker.h"
#include "TrackerDialog.h"
#include "TrackerDoc.h"
#include "TrackerProtocol.h"
#include "ServerSession.h"
#include "SubPanelBuddyList.h"
#include "SubPanelTrackerState.h"
#include "FileSystem.h"

#include <VGUI_Button.h>
#include <VGUI_Controls.h>
#include <VGUI_ILocalize.h>
#include <VGUI_IInput.h>
#include <VGUI_IScheme.h>
#include <VGUI_ISurface.h>
#include <VGUI_ISystem.h>
#include <VGUI_IVGui.h>
#include <VGUI_Menu.h>
#include <VGUI_MenuItem.h>
#include <VGUI_MenuButton.h>
#include <VGUI_MessageBox.h>
#include "FileSystem.h"



using namespace vgui;

static CTrackerDialog *s_pTrackerDialog = NULL;

CSysModule *g_hServerBrowserModule = NULL;

IServerBrowser *g_pIServerBrowser = NULL;

static CTrackerDoc *g_pTrackerDoc = NULL;

// time in seconds before we go to sleep
static const int TIME_AUTOAWAY = (60 * 15);
static const int TIME_AUTOSNOOZE = (60 * 120);

//-----------------------------------------------------------------------------
// Purpose: Returns a pointer to the instance of the TrackerDialog
//-----------------------------------------------------------------------------
CTrackerDialog *CTrackerDialog::GetInstance()
{
	return s_pTrackerDialog;
}

//-----------------------------------------------------------------------------
// Purpose: Returns a pointer to the document
// Output : CTrackerDoc
//-----------------------------------------------------------------------------
CTrackerDoc *GetDoc()
{
	return g_pTrackerDoc;
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
CTrackerDialog::CTrackerDialog() : Frame(NULL, "TrackerDialog")
{
	SetTitle("#TrackerUI_Friends_Title", true);

	SetBounds(20, 20, 200, 400);
	SetMinimumSize(160, 250);

	m_pTrackerButton = NULL;
	m_pBuddyListPanel = NULL;
	m_pStatePanel = NULL;
	m_bOnline = false;
	m_iLoginTransitionPixel = -1;

	m_hDialogLoginUser = NULL;

	s_pTrackerDialog = this;
	m_bInGame = false;
	m_bNeedToSaveUserData = false;
	m_bNeedUpdateToFriendStatus = false;
	m_bInAutoAwayMode = false;

	m_pTrackerMenu = NULL;

	// tracker doc
	g_pTrackerDoc = new CTrackerDoc();
}

//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CTrackerDialog::~CTrackerDialog()
{
	system()->SetWatchForComputerUse(false);
	ServerSession().RemoveNetworkMessageWatch(this);

	delete g_pTrackerDoc;
	g_pTrackerDoc = NULL;
}

//-----------------------------------------------------------------------------
// Purpose: Tries to Start tracker
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool CTrackerDialog::Start()
{
	// set up some VGUI
	Initialize();

	// try and load the user
	KeyValues *pAppData = ::GetDoc()->Data()->FindKey("App", true);
	int currentUID = pAppData->GetInt("uid", 0);
	if (currentUID)
	{
		StartTrackerWithUser(currentUID);
	}

	return true;
}

//-----------------------------------------------------------------------------
// Purpose: Checks for auto-away
//-----------------------------------------------------------------------------
void CTrackerDialog::OnTick()
{
	ServerSession().RunFrame();

	//!! hack, reset the login transition slide if we're not visible
	if (!IsVisible())
	{
		m_bOnline = ServerSession().IsConnectedToServer();
		m_iLoginTransitionPixel = -1;
	}

	// check auto-away status
	if (Tracker_StandaloneMode())
	{
		int currentStatus = ServerSession().GetStatus();

		if (m_bInAutoAwayMode)
		{
			// check for going back to normal status
			double lastTime = system()->GetTimeSinceLastUse();
			if (lastTime < TIME_AUTOAWAY)
			{
				OnUserChangeStatus(COnlineStatus::ONLINE);
				m_bInAutoAwayMode = false;
			}
			else if (currentStatus == COnlineStatus::AWAY && lastTime > TIME_AUTOSNOOZE)
			{
				// check for going to mega-away status
				OnUserChangeStatus(COnlineStatus::SNOOZE);
			}
		}
		else if (currentStatus == COnlineStatus::ONLINE)
		{
			// check for auto-away
			if (system()->GetTimeSinceLastUse() > TIME_AUTOAWAY)
			{
				OnUserChangeStatus(COnlineStatus::AWAY);
				m_bInAutoAwayMode = true;
			}
		}
		else if (currentStatus == COnlineStatus::SNOOZE)
		{
			// we shouldn't be snoozing if we're not in auto-away mode
			OnUserChangeStatus(COnlineStatus::ONLINE);
		}
	}
}

//-----------------------------------------------------------------------------
// Purpose: brings tracker to the foreground
//-----------------------------------------------------------------------------
void CTrackerDialog::Activate()
{
	surface()->SetMinimized(GetVPanel(), false);
	SetVisible(true);
	MoveToFront();
	RequestFocus();
	InvalidateLayout();
	m_pBuddyListPanel->InvalidateAll();
	m_pStatePanel->InvalidateLayout();

	if (::GetDoc()->GetUserID() <= 0)
	{
		PopupCreateNewUserDialog(true);
	}
}

//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTrackerDialog::ShutdownUI()
{
	// save off our current status
	int currentStatus = ServerSession().GetStatus();
	GetDoc()->Data()->SetInt("User/LastStatus", currentStatus);

	// Stop watching the keyboard
	system()->SetWatchForComputerUse(false);

	// save off our minimized status
	if (Tracker_StandaloneMode())
	{
		GetDoc()->Data()->SetInt("App/StartMinimized", !IsVisible());

		int x, y, wide, tall;
		GetBounds(x, y, wide, tall);
		GetDoc()->Data()->SetInt("App/win_x", x);
		GetDoc()->Data()->SetInt("App/win_y", y);
		GetDoc()->Data()->SetInt("App/win_w", wide);
		GetDoc()->Data()->SetInt("App/win_t", tall);
	}
	else
	{
	   	int x, y, wide, tall;
		GetBounds(x, y, wide, tall);
		GetDoc()->Data()->SetInt("App/win_game_x", x);
		GetDoc()->Data()->SetInt("App/win_game_y", y);
		GetDoc()->Data()->SetInt("App/win_game_w", wide);
		GetDoc()->Data()->SetInt("App/win_game_t", tall);
	}

	// save our data to disk
	// only "App/" and "User/" are saved, any other sections are temporary
	OnSaveUserData();

	// close down all dialogs
	GetDoc()->ShutdownAllDialogs();
	for ( int i = m_hChatDialogs.GetCount() - 1; i >= 0; i--)
	{
		if (m_hChatDialogs[i])
		{
			ivgui()->PostMessage(m_hChatDialogs[i]->GetVPanel(), new KeyValues("Close"), this->GetVPanel());
		}
	}

	// send a network message detailing that we are logging off
	ServerSession().UserSelectNewStatus(COnlineStatus::OFFLINE);
}

//-----------------------------------------------------------------------------
// Purpose: closes tracker, shuts down it's networking, saves any data
//-----------------------------------------------------------------------------
void CTrackerDialog::Shutdown()
{
	// shutdown the UI
	ShutdownUI();

	// close down the networking
	ServerSession().Shutdown();
}

//-----------------------------------------------------------------------------
// Purpose: Opens the login user wizard
//-----------------------------------------------------------------------------
void CTrackerDialog::PopupCreateNewUserDialog(bool performConnectionTest)
{
	if (m_hDialogLoginUser)
	{
		// dialog is already active
		m_hDialogLoginUser->MoveToFront();
		return;
	}

	// if we're not logged in, hide the main dialog
	if (::GetDoc()->GetUserID() <= 0)
	{
		SetVisible(false);
		surface()->SetMinimized(this->GetVPanel(), true);
	}

	m_hDialogLoginUser = new CDialogLoginUser();
	m_hDialogLoginUser->AddActionSignalTarget(this);

	// titles
	m_hDialogLoginUser->SetTitle("#TrackerUI_Friends_LoginUserTitle", true);

	m_hDialogLoginUser->RequestFocus();

	// Start the panel (it will call back when done)
	m_hDialogLoginUser->Run(performConnectionTest);

	if (ServerSession().GetStatus() >= COnlineStatus::ONLINE)
	{
		// log out before the user tries to log in as a different user
		ServerSession().UserSelectNewStatus(COnlineStatus::OFFLINE);
	}
}


//-----------------------------------------------------------------------------
// Purpose: Starts tracker main panel with the specified user
//-----------------------------------------------------------------------------
void CTrackerDialog::StartTrackerWithUser(int userID)
{
	GetDoc()->Data()->SetInt("App/UID", userID);

	// record this last login in the registry
	vgui::system()->SetRegistryInteger("HKEY_CURRENT_USER\\Software\\Valve\\Tracker\\LastUserID", userID);

	m_pBuddyListPanel->Clear();

	// load the user-specific data
	GetDoc()->LoadUserData(userID);

	// fire up the main panel
	SetEnabled(true);

	// always Start invisible
	SetVisible(false);

	// set our initial position
	int x, y, wide, tall;
	GetBounds(x, y, wide, tall);
	y=0;
	int swide, stall;
	surface()->GetScreenSize(swide, stall);
	int trackerDefaultWidth = 200;

	if (Tracker_StandaloneMode())
	{
		SetBounds(GetDoc()->Data()->GetInt("App/win_x", swide - wide), 
		GetDoc()->Data()->GetInt("App/win_y", y), 
		GetDoc()->Data()->GetInt("App/win_w", trackerDefaultWidth), 
		GetDoc()->Data()->GetInt("App/win_t", tall));
	}
	else
	{			
		
		SetBounds(GetDoc()->Data()->GetInt("App/win_game_x", swide - wide), 
		GetDoc()->Data()->GetInt("App/win_game_y", 154), 
		GetDoc()->Data()->GetInt("App/win_game_w", wide), 
		GetDoc()->Data()->GetInt("App/win_game_t", tall - (155)));	
	}
	
	GetBounds(x, y, wide, tall);

	// make sure we're not out of range
	int sw, st;
	surface()->GetScreenSize(sw, st);
	if (x + wide > sw)
	{
		x = sw - wide;
	}
	if (y + tall > st)
	{
		y = st - tall;
	}
	if (x < 0)
	{
		x = 0;
	}
	if (y < 0)
	{
		y = 0;
	}
	SetPos(x, y);

	// tell the panel to update
	InvalidateLayout(false);

	int prevStatus = ::GetDoc()->Data()->GetInt("User/LastStatus", COnlineStatus::ONLINE);
	if (prevStatus < COnlineStatus::ONLINE)
	{
		prevStatus = COnlineStatus::ONLINE;
	}

	// Start login procedure
	ServerSession().UserSelectNewStatus(prevStatus);

	// notify whomever ran us
	Tracker_GetRunGameEngineInterface()->SetTrackerUserID(userID);
}


//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CTrackerDialog::Initialize( void )
{
	// set our frame panel
	m_pBuddyListPanel = new CSubPanelBuddyList(this, "BuddyList");
	m_pStatePanel = new CSubPanelTrackerState(this, "FriendsState");

	// set up our controls
	/*
	KeyValues *command = new KeyValues("UserChangeStatus");

	command->SetInt("status", COnlineStatus::OFFLINE);
	m_pOnlineStatusButton->AddItem("offline", command->MakeCopy(), this);
	command->SetInt("status", COnlineStatus::AWAY);
	m_pOnlineStatusButton->AddItem("away", command->MakeCopy(), this);
	command->SetInt("status", COnlineStatus::BUSY);
	m_pOnlineStatusButton->AddItem("busy", command->MakeCopy(), this);
	command->SetInt("status", COnlineStatus::ONLINE);
	m_pOnlineStatusButton->AddItem("online", command->MakeCopy(), this);
	*/

	// network message watch
	ServerSession().AddNetworkMessageWatch(this, TSVC_FRIENDS);
	ServerSession().AddNetworkMessageWatch(this, TCL_MESSAGE);
	ServerSession().AddNetworkMessageWatch(this, TSVC_MESSAGE);
	ServerSession().AddNetworkMessageWatch(this, TSVC_LOGINOK);
	ServerSession().AddNetworkMessageWatch(this, TSVC_LOGINFAIL);
	ServerSession().AddNetworkMessageWatch(this, TSVC_GAMEINFO);
	ServerSession().AddNetworkMessageWatch(this, TSVC_FRIENDINFO);
	ServerSession().AddNetworkMessageWatch(this, TCL_USERBLOCK);
	ServerSession().AddNetworkMessageWatch(this, TCL_ADDEDTOCHAT);


	//// CONTEXT MENU ////
	m_pTrackerButton = new MenuButton(this, "TrackerMenuButton", "&Options");
	m_pTrackerButton->SetOpenDirection(MenuButton::UP);
	m_pTrackerMenu = new Menu(m_pTrackerButton, "TrackerMenu");

	// add a hierarchial checkable menu
	Menu *statusSubMenu = new Menu(NULL, "StatusMenu");
	statusSubMenu->AddCheckableMenuItem("Online", new KeyValues("UserChangeStatus", "status", COnlineStatus::ONLINE), this);
	statusSubMenu->AddCheckableMenuItem("Away", new KeyValues("UserChangeStatus", "status", COnlineStatus::AWAY), this);
	statusSubMenu->AddCheckableMenuItem("Busy", new KeyValues("UserChangeStatus", "status", COnlineStatus::BUSY), this);
	statusSubMenu->AddCheckableMenuItem("Offline", new KeyValues("UserChangeStatus", "status", COnlineStatus::OFFLINE), this);

	m_pTrackerMenu->AddMenuItem(new MenuItem(NULL, "MyStatus", "&My Status", statusSubMenu));
	m_pTrackerMenu->AddMenuItem("&Add Friends", "OpenFindBuddyDialog", this);
	m_pTrackerMenu->AddMenuItem("&Edit My Profile", "OpenOptionsDialog", this);
	if (Tracker_StandaloneMode())
	{
		// only let users change login info outside of game
		m_pTrackerMenu->AddMenuItem("&Change Login ", "OpenCreateNewUserDialog", this);
	}

	m_pTrackerButton->SetMenu(m_pTrackerMenu);

	m_pContextMenu = new Menu(NULL, NULL);
	m_pContextMenu->AddMenuItem("&Open", "Open", this);
	m_pContextMenu->AddMenuItem("O&ptions", "OpenOptionsDialog", this);
	m_pContextMenu->AddMenuItem("Find &Game", "ServerBrowser", this);
	m_pContextMenu->AddMenuItem("&Hide", "Minimize", this);
	m_pContextMenu->AddMenuItem("&About ", "About", this);
	m_pContextMenu->SetVisible(false);
	surface()->CreatePopup(m_pContextMenu->GetVPanel(), false);
	surface()->SetAsToolBar(m_pContextMenu->GetVPanel(), true);


	// set initial online status to offline
	// do this after you create the menus so they will be checked properly

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -