Пример #1
0
static void http_handler(struct evhttp_request *req, void *args)
{
	struct EventContext *eventContext = (struct EventContext *)args;
	KonohaContext *kctx = eventContext->httpContext;
	struct evbuffer *body = evhttp_request_get_input_buffer(req);
	size_t len = evbuffer_get_length(body);
	unsigned char *requestLine;
	struct evbuffer *buf = evbuffer_new();

	switch(req->type) {
		case EVHTTP_REQ_POST:
			requestLine = evbuffer_pullup(body, -1);
			requestLine[len] = '\0';
			struct JsonBuf jsonbuf = {};
			if(PLATAPI ParseJson(kctx, &jsonbuf, (char *)requestLine, strlen((char *)requestLine), NULL)) {
				pthread_mutex_lock(&eventContext->lock);
				if(enqueueRawEventToLocalQueue(eventContext->queue, (RawEvent *)&jsonbuf) == true) {
					pthread_mutex_unlock(&eventContext->lock);
					evhttp_send_reply(req, HTTP_OK, "OK", buf);
				}
				*(eventContext->safePointRef) |= SafePoint_Event;
			}
			else {
				evhttp_send_error(req, HTTP_SERVUNAVAIL, "Event queue is full");
			}
			break;
		default:
			evhttp_send_error(req, HTTP_BADREQUEST, "Available POST only");
			break;
	}
	evbuffer_free(buf);
}
Пример #2
0
int DoAcoustIdWebRequest( vlc_object_t *p_obj, acoustid_fingerprint_t *p_data )
{
    if ( !p_data->psz_fingerprint ) return VLC_SUCCESS;

    char *psz_url;
    if( unlikely(asprintf( &psz_url, "https://fingerprint.videolan.org/"
                           "acoustid.php?meta=recordings+tracks+usermeta+"
                           "releases&duration=%d&fingerprint=%s",
                           p_data->i_duration, p_data->psz_fingerprint ) < 1 ) )
         return VLC_EGENERIC;

    msg_Dbg( p_obj, "Querying AcoustID from %s", psz_url );
    int i_saved_flags = p_obj->obj.flags;
    p_obj->obj.flags |= OBJECT_FLAGS_NOINTERACT;

    stream_t *p_stream = vlc_stream_NewURL( p_obj, psz_url );

    free( psz_url );
    p_obj->obj.flags = i_saved_flags;
    if ( p_stream == NULL )
        return VLC_EGENERIC;

    stream_t *p_chain = vlc_stream_FilterNew( p_stream, "inflate" );
    if( p_chain )
        p_stream = p_chain;

    /* read answer */
    char *p_buffer = NULL;
    int i_ret = 0;
    for( ;; )
    {
        int i_read = 65536;

        if( i_ret >= INT_MAX - i_read )
            break;

        p_buffer = realloc_or_free( p_buffer, 1 + i_ret + i_read );
        if( unlikely(p_buffer == NULL) )
        {
            vlc_stream_Delete( p_stream );
            return VLC_ENOMEM;
        }

        i_read = vlc_stream_Read( p_stream, &p_buffer[i_ret], i_read );
        if( i_read <= 0 )
            break;

        i_ret += i_read;
    }
    vlc_stream_Delete( p_stream );
    p_buffer[i_ret] = 0;

    if ( ParseJson( p_obj, p_buffer, & p_data->results ) )
        msg_Dbg( p_obj, "results count == %d", p_data->results.count );
    else
        msg_Dbg( p_obj, "No results" );
    free( p_buffer );

    return VLC_SUCCESS;
}
Пример #3
0
	VarValue Call(RCString method, const vector<VarValue>& params = vector<VarValue>()) {
		Ext::WebClient wc = GetWebClient();
		wc.Proxy = nullptr;		//!!!?
		wc.CacheLevel = RequestCacheLevel::BypassCache;
		wc.Credentials.UserName = !Login.empty() ? Login : RpcUrl.UserName;
		wc.Credentials.Password = !Password.empty() ? Password : RpcUrl.Password;

		String sjson;
		try {
			DBG_LOCAL_IGNORE_CONDITION_OBJ(error_condition(500, http_category()));

			sjson = wc.UploadString(RpcUrl.ToString(), JsonRpc.Request(method, params));
		} catch (WebException& ex) {
			if (ex.code() == http_error::unauthorized)
				throw;
			sjson = ex.Result;
		}
#ifdef X_DEBUG//!!!D
		cout << sjson << endl;
#endif

		EXT_LOCKED(MtxHeaders, Headers = wc.get_ResponseHeaders());
/*!!!R			XStratum = h.Get("X-Stratum");
			XSwitchTo = h.Get("X-Switch-To");
			XHostList = h.Get("X-Host-List");*/

		return JsonRpc.ProcessResponse(ParseJson(sjson));
	}
void CDlgExpEditorDM::ProcessUpdate( const char* str )
{
	CDlgSvg * pSvg = GetSvgDilogPtr();
	if ( pSvg == NULL ) return;

	CWebMethodParamData * pParam = NULL;
	CWebMethodData wmd;

	wmd.m_sMethodName = "dataMappingExpUpdate";

	pParam = new CWebMethodParamData();
	pParam->m_sName = "json";
	pParam->m_sValue = str;
	wmd.m_vParams.push_back(pParam);
	BOOL b = pSvg->InvokeJsMethod( &wmd );

	if (!b || wmd.m_sResult.IsEmpty()) 
	{
		MessageBox("调用页面方法dataMappingExpUpdate失败!", g_lpszAppTitle, MB_ICONERROR);
		EndDialog(0);//无返回结果
		return;
	}

	else
	{
		//ParseJson(str);
		ParseJson(wmd.m_sResult);
	}

}
Пример #5
0
v8::Local<v8::Value> TNodeJsUtil::ParseJson(v8::Isolate* Isolate, const PJsonVal& JsonVal) {
    v8::EscapableHandleScope HandleScope(Isolate);
    
    if (!JsonVal->IsDef()) {
        return v8::Undefined(Isolate);
    }
    else if (JsonVal->IsBool()) {
        return v8::Boolean::New(Isolate, JsonVal->GetBool());
    }
    else if (JsonVal->IsNull()) {
        return v8::Null(Isolate);
    }
    else if (JsonVal->IsNum()) {
        return HandleScope.Escape(v8::Number::New(Isolate, JsonVal->GetNum()));
    }
    else if (JsonVal->IsStr()) {
        return HandleScope.Escape(v8::String::NewFromUtf8(Isolate, JsonVal->GetStr().CStr()));
    }
    else if (JsonVal->IsArr()) {
        const uint Len = JsonVal->GetArrVals();

        v8::Local<v8::Array> ResArr = v8::Array::New(Isolate, Len);

        for (uint i = 0; i < Len; i++) {
            ResArr->Set(i, ParseJson(Isolate, JsonVal->GetArrVal(i)));
        }

        return HandleScope.Escape(ResArr);
    }
    else if (JsonVal->IsObj()) {
        v8::Local<v8::Object> ResObj = v8::Object::New(Isolate);

        const int NKeys = JsonVal->GetObjKeys();

        for (int i = 0; i < NKeys; i++) {
            TStr Key;    PJsonVal Val;
            JsonVal->GetObjKeyVal(i, Key, Val);

            ResObj->Set(v8::String::NewFromUtf8(Isolate, Key.CStr()), ParseJson(Isolate, Val));
        }

        return HandleScope.Escape(ResObj);
    }
    else {
        throw TExcept::New("Invalid JSON!", "TNodeJsUtil::ParseJson");
    }
}
Пример #6
0
static void AddSignalEvent(KonohaContext *kctx, struct EventContext *eventContext, KTraceInfo *trace)
{
	size_t i;
	for(i = 0; i < 32; i++) {
		siginfo_t *siginfo = eventContext->siginfo[i];
		eventContext->siginfo[i] = NULL;
		if(siginfo != NULL) {
			char buf[BUFSIZ];
			struct JsonBuf jsonbuf = {};
			snprintf(buf, sizeof(buf), "{\"event\": \"signal\", \"signal\": %d}", (int)(i+1));
			if(PLATAPI ParseJson(kctx, &jsonbuf, buf, strlen(buf), trace)) {
				enqueueRawEventToLocalQueue(eventContext->queue, (RawEvent *)&jsonbuf);
			}
		}
	}
}
Пример #7
0
void CSvrSocket::Process(UINT nReciveLen)
{
	UINT uiEndPos = m_nOffset + nReciveLen;
	UINT uiOffset = 0;

	char* buffer = m_Buffer + m_nOffset;	// 当前正在处理的消息开始位置
	int  uiLeftSize = uiEndPos - uiOffset;	// 剩余尚未处理的缓冲区字节数

	while (1)
	{
		if (uiLeftSize >= sizeof(MsgHeader))
		{
			MsgHeader* pHeader = (MsgHeader*)buffer;
			if ( uiLeftSize < pHeader->len+sizeof(MsgHeader))
			{
				break;
			}

			char* json = new char[pHeader->len + 1];
			memset(json, 0, pHeader->len + 1);
			memcpy(json, buffer + sizeof(MsgHeader), pHeader->len);

			CBaseMsg* Msg = NULL;
			ParseJson(&Msg, json, pHeader->type);
			memcpy(&Msg->Header, buffer, sizeof(MsgHeader));
			SendMsg(Msg, json);
			delete json;


			buffer += pHeader->len + sizeof(MsgHeader);
			uiLeftSize -= pHeader->len + sizeof(MsgHeader);
		}
		else   // 剩余的长度小于消息的实际长度,此时可能消息头部并未收全
		{
			if (uiLeftSize && uiOffset)
			{
				memmove(m_Buffer, buffer, uiLeftSize);
			}

			m_nOffset = uiLeftSize;
			break;
		}
	}
}
Пример #8
0
static PJVAL MakeValue(PGLOBAL g, UDF_ARGS *args, int i)
{
  char *sap = (args->arg_count > (unsigned)i) ? args->args[i] : NULL;
  PJSON jsp;
  PJVAL jvp = new(g) JVALUE;

  if (sap) switch (args->arg_type[i]) {
    case STRING_RESULT:
      if (args->lengths[i]) {
        if (IsJson(args, i)) {
          if (!(jsp = ParseJson(g, sap, args->lengths[i], 0)))
            push_warning(current_thd, Sql_condition::WARN_LEVEL_WARN, 0, 
                         g->Message);

          if (jsp && jsp->GetType() == TYPE_JVAL)
            jvp = (PJVAL)jsp;
          else
            jvp->SetValue(jsp);

        } else
          jvp->SetString(g, MakePSZ(g, args, i));

        } // endif str

      break;
    case INT_RESULT:
      jvp->SetInteger(g, *(int*)sap);
      break;
    case REAL_RESULT:
      jvp->SetFloat(g, *(double*)sap);
      break;
    case DECIMAL_RESULT:
      jvp->SetFloat(g, atof(MakePSZ(g, args, i)));
      break;
    case TIME_RESULT:
    case ROW_RESULT:
    case IMPOSSIBLE_RESULT:
    default:
      break;
    } // endswitch arg_type

  return jvp;
} // end of MakeValue
Пример #9
0
int DoAcoustIdWebRequest( vlc_object_t *p_obj, acoustid_fingerprint_t *p_data )
{
    int i_ret;
    int i_status;
    struct webrequest_t request = { NULL, NULL, NULL };

    if ( !p_data->psz_fingerprint ) return VLC_SUCCESS;

    i_ret = asprintf( & request.psz_url,
              "http://fingerprint.videolan.org/acoustid.php?meta=recordings+tracks+usermeta+releases&duration=%d&fingerprint=%s",
              p_data->i_duration, p_data->psz_fingerprint );
    if ( i_ret < 1 ) return VLC_EGENERIC;

    vlc_cleanup_push( cancelDoAcoustIdWebRequest, &request );

    msg_Dbg( p_obj, "Querying AcoustID from %s", request.psz_url );
    request.p_stream = stream_UrlNew( p_obj, request.psz_url );
    if ( !request.p_stream )
    {
        i_status = VLC_EGENERIC;
        goto cleanup;
    }

    /* read answer */
    i_ret = 0;
    for( ;; )
    {
        int i_read = 65536;

        if( i_ret >= INT_MAX - i_read )
            break;

        request.p_buffer = realloc_or_free( request.p_buffer, 1 + i_ret + i_read );
        if( !request.p_buffer )
        {
            i_status = VLC_ENOMEM;
            goto cleanup;
        }

        i_read = stream_Read( request.p_stream, &request.p_buffer[i_ret], i_read );
        if( i_read <= 0 )
            break;

        i_ret += i_read;
    }
    stream_Delete( request.p_stream );
    request.p_stream = NULL;
    request.p_buffer[ i_ret ] = 0;

    int i_canc = vlc_savecancel();
    if ( ParseJson( p_obj, request.p_buffer, & p_data->results ) )
    {
        msg_Dbg( p_obj, "results count == %d", p_data->results.count );
    } else {
        msg_Dbg( p_obj, "No results" );
    }
    vlc_restorecancel( i_canc );
    i_status = VLC_SUCCESS;

cleanup:
    vlc_cleanup_run( );
    return i_status;
}
Пример #10
0
void RunFileTest(const char * szFileName)
{
	const cn_cbor * pControl = NULL;

	pControl = ParseJson(szFileName);

	//
	//  If we are given a file name, then process the file name
	//

	if (pControl == NULL) {
		CFails += 1;
		return;
	}

	//  To find out what we are doing we need to get the correct item

	const cn_cbor * pInput = cn_cbor_mapget_string(pControl, "input");

	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP)) {
		fprintf(stderr, "No or bad input section");
		exit(1);
	}

	if (cn_cbor_mapget_string(pInput, "mac") != NULL) {
#if INCLUDE_MAC
		if (ValidateMAC(pControl)) {
			BuildMacMessage(pControl);
		}
#endif
	}
	else if (cn_cbor_mapget_string(pInput, "mac0") != NULL) {
#if INCLUDE_MAC0
		if (ValidateMac0(pControl)) {
			BuildMac0Message(pControl);
		}
#endif
	}
	else if (cn_cbor_mapget_string(pInput, "enveloped") != NULL) {
#if INCLUDE_ENCRYPT
		if (ValidateEnveloped(pControl)) {
			BuildEnvelopedMessage(pControl);
		}
#endif
	}
	else if (cn_cbor_mapget_string(pInput, "sign") != NULL) {
#if INCLUDE_SIGN
		if (ValidateSigned(pControl)) {
			BuildSignedMessage(pControl);
		}
#endif
	}
	else if (cn_cbor_mapget_string(pInput, "sign0") != NULL) {
#if INCLUDE_SIGN0
		if (ValidateSign0(pControl)) {
			BuildSign0Message(pControl);
		}
#endif
	}
	else if (cn_cbor_mapget_string(pInput, "encrypted") != NULL) {
#if INCLUDE_ENCRYPT0
		if (ValidateEncrypt(pControl)) {
			BuildEncryptMessage(pControl);
		}
#endif
	}

	return;
}
Пример #11
0
void RunMemoryTest(const char * szFileName)
{
#ifdef USE_CBOR_CONTEXT
	unsigned int iFail;
	const cn_cbor * pControl = ParseJson(szFileName);

	if (pControl == NULL) {
		CFails += 1;
		return;
	}

	//
	//  To find out what we are doing we need to get the correct item

	const cn_cbor * pInput = cn_cbor_mapget_string(pControl, "input");

	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP)) {
		fprintf(stderr, "No or bad input section");
		exit(1);
	}

	//
	bool fValidateDone = false;
	bool fBuildDone = false;

	for (iFail = 0; !fValidateDone || !fBuildDone; iFail++) {
		context = CreateContext(iFail);

		if (cn_cbor_mapget_string(pInput, "mac") != NULL) {
#if INCLUDE_MAC
			if (!fValidateDone) {
				context = CreateContext(iFail);
				CFails = 0;
				ValidateMAC(pControl);
				if (CFails == 0) fValidateDone = true;
			}

			if (!fBuildDone) {
				context = CreateContext(iFail);
				CFails = 0;
				BuildMacMessage(pControl);
				if (CFails == 0) fBuildDone = true;
			}
#else
			fValidateDone = true;
			fBuildDone = true;
#endif
		}
		else if (cn_cbor_mapget_string(pInput, "mac0") != NULL) {
#if INCLUDE_MAC0
			if (!fValidateDone) {
				context = CreateContext(iFail);
				CFails = 0;
				ValidateMac0(pControl);
				if (CFails == 0) fValidateDone = true;
			}

			if (!fBuildDone) {
				context = CreateContext(iFail);
				CFails = 0;
				BuildMac0Message(pControl);
				if (CFails == 0) fBuildDone = true;
			}
#else
			fValidateDone = true;
			fBuildDone = true;
#endif
		}
		else if (cn_cbor_mapget_string(pInput, "encrypted") != NULL) {
#if INCLUDE_ENCRYPT0
			if (!fValidateDone) {
				context = CreateContext(iFail);
				CFails = 0;
				ValidateEncrypt(pControl);
				if (CFails == 0) fValidateDone = true;
			}

			if (!fBuildDone) {
				context = CreateContext(iFail);
				CFails = 0;
				BuildEncryptMessage(pControl);
				if (CFails == 0) fBuildDone = true;
			}
#else
			fValidateDone = true;
			fBuildDone = true;
#endif
		}
		else if (cn_cbor_mapget_string(pInput, "enveloped") != NULL) {
#if INCLUDE_ENCRYPT
			if (!fValidateDone) {
				context = CreateContext(iFail);
				CFails = 0;
				ValidateEnveloped(pControl);
				if (CFails == 0) fValidateDone = true;
			}

			if (!fBuildDone) {
				context = CreateContext(iFail);
				CFails = 0;
				BuildEnvelopedMessage(pControl);
				if (CFails == 0) fBuildDone = true;
			}
#else
			fValidateDone = true;
			fBuildDone = true;
#endif
		}
		else if (cn_cbor_mapget_string(pInput, "sign") != NULL) {
#if INCLUDE_SIGN
			if (!fValidateDone) {
				context = CreateContext(iFail);
				CFails = 0;
				ValidateSigned(pControl);
				if (CFails == 0) fValidateDone = true;
			}

			if (!fBuildDone) {
				context = CreateContext(iFail);
				CFails = 0;
				BuildSignedMessage(pControl);
				if (CFails == 0) fBuildDone = true;
			}
#else
			fValidateDone = true;
			fBuildDone = true;
#endif
		}
		else if (cn_cbor_mapget_string(pInput, "sign0") != NULL) {
#if INCLUDE_SIGN0
			if (!fValidateDone) {
				context = CreateContext(iFail);
				CFails = 0;
				ValidateSign0(pControl);
				if (CFails == 0) fValidateDone = true;
			}

			if (!fBuildDone) {
				context = CreateContext(iFail);
				CFails = 0;
				BuildSign0Message(pControl);
				if (CFails == 0) fBuildDone = true;
			}
#else
			fValidateDone = true;
			fBuildDone = true;
#endif
		}
	}
	CFails = 0;
	context = NULL;
#else
	return;
#endif
}
Пример #12
0
    ret["b"] = colour.b;
    ret["a"] = colour.a;
    return ret;
}

inline std::ostream& operator<<(std::ostream& os, const Colour& colour)
{
    os << toJson(colour).serialize();
    return os;
}

inline std::istream& operator>>(std::istream& is, Colour& colour)
{
    json::value val;
    json::parse(val,is);
    colour = ParseJson(val);
    return is;
}

inline void glColour(const Colour& c)
{
    glColor4f(c.r,c.g,c.b,c.a);
}

ConsoleView::ConsoleView(ConsoleInterpreter* interpreter)
    : interpreter(interpreter),
      font(GlFont::I()),
      hiding(false),
      bottom(1.0f),
      background_colour(0.2f, 0.0f, 0.0f, 0.6f),
      animation_speed(0.2)
Пример #13
0
void
Scene::InitFromJson(
    const char* filepath
    )
{
    // -- Parse JSON
    Json::Value root;
    bool success = ParseJson(filepath, root);
    if (!success) {
        // Failed parsing JSON
        return;
    }

    // -- Get container information
    const Json::Value containerDimJson = root["containerDim"];

    glm::vec3 containerDim(
        containerDimJson["scaleX"].asFloat(),
        containerDimJson["scaleY"].asFloat(),
        containerDimJson["scaleZ"].asFloat()
        );

    // Create geometry for the container
    m_fluidContainer = new Box(DrawMode_Wireframe);
    m_fluidContainer->Scale(containerDim.x, containerDim.y, containerDim.z);
    m_fluidContainer->Create();

    // -- Get particle information
    const Json::Value particleDimJson = root["particleDim"];
    glm::vec3 particleDim(
        particleDimJson["boundX"].asFloat(),
        particleDimJson["boundY"].asFloat(),
        particleDimJson["boundZ"].asFloat()
        );

    const Json::Value particleCenterJson = root["particleCenter"];
    glm::vec3 particleCenter(
        particleCenterJson["centerX"].asFloat(),
        particleCenterJson["centerY"].asFloat(),
        particleCenterJson["centerZ"].asFloat()
        );

    const float tankHeight = root["tankHeight"].asFloat();
    const float separation = root["particleSeparation"].asFloat();
    const float cellSize = root["cellSize"].asFloat();
    const float stiffness = root["stiffness"].asFloat();
    const float viscosity = root["viscosity"].asFloat();
    const float mass = root["mass"].asFloat();
    const float restDensity = root["restDensity"].asFloat();

    // -- Initialize fluid solvers
    m_fluidSolver = new SPHSolver(
        containerDim,
        particleDim,
        particleCenter,
        tankHeight,
        separation,
        cellSize,
        stiffness,
        viscosity,
        mass,
        restDensity
        );

    // -- Initialize fluid geo
    m_fluidGeo = new FluidGeo(
        m_fluidSolver->ParticlePositions(),
        m_fluidSolver->ParticleVelocities(),
        m_fluidSolver->ParticleSpawnTimes(),
        m_fluidSolver->ParticleColors()
        );
    m_fluidGeo->Create();

    // -- Solid object
    if (m_enableTestBox1) {
        CreateTestBoxOne();
    }

    if (m_enableTestBox2) {
        CreateTestBoxTwo();
    }
}
Пример #14
0
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static uint32_t lanLastPing = 0;
	static HFONT _hFont = 0;
	switch (message)
	{
	case WM_CREATE:
	{
		HFONT hFont = 0;

		NONCLIENTMETRICS ncm = { sizeof(ncm) };
		if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0))
		{
			hFont = CreateFontIndirect(&ncm.lfMessageFont);
			_hFont = hFont;
		}
		if (!hFont)
			hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);

		RECT rcClient;
		GetClientRect(hWnd, &rcClient);

		g_hWndListViewServers = CreateWindow(WC_LISTVIEW, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | LVS_OWNERDATA, 1, 21, rcClient.right - UI_PLAYERLIST_WIDTH - 4, rcClient.bottom - UI_SERVERINFO_HEIGHT - 21 - 2, hWnd, nullptr, g_hInst, nullptr);
		if (g_hWndListViewServers)
		{
			SetWindowTheme(g_hWndListViewServers, L"Explorer", nullptr);
			ListView_SetExtendedListViewStyle(g_hWndListViewServers, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);

			LVCOLUMN lvc;
			lvc.mask = LVCF_WIDTH;
			lvc.cx = 30;
			ListView_InsertColumn(g_hWndListViewServers, 0, &lvc);

			lvc.mask = LVCF_WIDTH | LVCF_TEXT;
			lvc.cx = 240;
			lvc.pszText = LoadStr(L"Server Name", IDS_SERVERNAME);
			ListView_InsertColumn(g_hWndListViewServers, 1, &lvc);

			lvc.cx = 60;
			lvc.pszText = LoadStr(L"Ping", IDS_PING);
			ListView_InsertColumn(g_hWndListViewServers, 2, &lvc);

			lvc.cx = 80;
			lvc.pszText = LoadStr(L"Players", IDS_PLAYERS);
			ListView_InsertColumn(g_hWndListViewServers, 3, &lvc);

			lvc.cx = 70;
			lvc.pszText = LoadStr(L"Version", IDS_VERSION);
			ListView_InsertColumn(g_hWndListViewServers, 4, &lvc);

			lvc.cx = 120;
			lvc.pszText = LoadStr(L"Gamemode", IDS_GAMEMODE);
			ListView_InsertColumn(g_hWndListViewServers, 5, &lvc);

			lvc.cx = 100;
			lvc.pszText = LoadStr(L"Map Name", IDS_MAPNAME);
			ListView_InsertColumn(g_hWndListViewServers, 6, &lvc);
		}

		g_hWndListViewHistory = CreateWindow(WC_LISTVIEW, nullptr, WS_CHILD | WS_CLIPSIBLINGS | LVS_REPORT | LVS_SHOWSELALWAYS | LVS_AUTOARRANGE | LVS_OWNERDATA, 1, 21, rcClient.right - UI_PLAYERLIST_WIDTH - 4, rcClient.bottom - UI_SERVERINFO_HEIGHT - 21 - 2, hWnd, nullptr, g_hInst, nullptr);
		if (g_hWndListViewHistory)
		{
			SetWindowTheme(g_hWndListViewHistory, L"Explorer", nullptr);
			ListView_SetExtendedListViewStyle(g_hWndListViewHistory, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);

			LVCOLUMN lvc;
			lvc.mask = LVCF_WIDTH;
			lvc.cx = 30;
			ListView_InsertColumn(g_hWndListViewHistory, 0, &lvc);

			lvc.mask = LVCF_WIDTH | LVCF_TEXT;
			lvc.cx = 220;
			lvc.pszText = LoadStr(L"Server Name", IDS_SERVERNAME);
			ListView_InsertColumn(g_hWndListViewHistory, 1, &lvc);

			lvc.cx = 60;
			lvc.pszText = LoadStr(L"Ping", IDS_PING);
			ListView_InsertColumn(g_hWndListViewHistory, 2, &lvc);

			lvc.cx = 80;
			lvc.pszText = LoadStr(L"Players", IDS_PLAYERS);
			ListView_InsertColumn(g_hWndListViewHistory, 3, &lvc);

			lvc.cx = 70;
			lvc.pszText = LoadStr(L"Version", IDS_VERSION);
			ListView_InsertColumn(g_hWndListViewHistory, 4, &lvc);

			lvc.cx = 100;
			lvc.pszText = LoadStr(L"Gamemode", IDS_GAMEMODE);
			ListView_InsertColumn(g_hWndListViewHistory, 5, &lvc);

			lvc.cx = 160;
			lvc.pszText = LoadStr(L"Last Played", IDS_LASTPLAYED);
			ListView_InsertColumn(g_hWndListViewHistory, 6, &lvc);
		}

		g_hWndTab = CreateWindow(WC_TABCONTROL, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 0, 0, rcClient.right - UI_PLAYERLIST_WIDTH, rcClient.bottom - UI_SERVERINFO_HEIGHT, hWnd, nullptr, g_hInst, nullptr);
		if (g_hWndTab)
		{
			SetWindowFont(g_hWndTab, hFont, FALSE);

			HIMAGELIST hTabIml = ImageList_Create(16, 16, ILC_COLOR32, 0, 0);
			if (hTabIml)
			{
				for (int i = IDI_FAVORITE; i <= IDI_HISTORY; ++i)
					ImageList_AddIcon(hTabIml, LoadIcon(g_hInst, MAKEINTRESOURCE(i)));
				TabCtrl_SetImageList(g_hWndTab, hTabIml);
			}

			TCITEM tie;
			tie.mask = TCIF_TEXT | TCIF_IMAGE;
			tie.iImage = 0;
			tie.pszText = LoadStr(L"Favorites", IDS_FAVORITES);
			TabCtrl_InsertItem(g_hWndTab, 0, &tie);

			tie.iImage = 1;
			tie.pszText = LoadStr(L"Internet", IDS_INTERNET);
			TabCtrl_InsertItem(g_hWndTab, 1, &tie);

			tie.iImage = 1;
			tie.pszText = LoadStr(L"Official", IDS_OFFICIAL);
			TabCtrl_InsertItem(g_hWndTab, 2, &tie);

			tie.iImage = 2;
			tie.pszText = LoadStr(L"Lan", IDS_LAN);
			TabCtrl_InsertItem(g_hWndTab, 3, &tie);

			tie.iImage = 3;
			tie.pszText = LoadStr(L"History", IDS_HISTORY);
			TabCtrl_InsertItem(g_hWndTab, 4, &tie);
		}

		g_hWndListViewPlayers = CreateWindowEx(0, WC_LISTVIEW, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOCOLUMNHEADER | LVS_SINGLESEL | LVS_OWNERDATA, rcClient.right - UI_PLAYERLIST_WIDTH + 1, 18, UI_PLAYERLIST_WIDTH - 2, rcClient.bottom - UI_SERVERINFO_HEIGHT - 18 - 2, hWnd, nullptr, g_hInst, nullptr);
		if (g_hWndListViewPlayers)
		{
			SetWindowTheme(g_hWndListViewPlayers, L"Explorer", nullptr);
			ListView_SetExtendedListViewStyle(g_hWndListViewPlayers, LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER);

			LVCOLUMN lvc;
			lvc.mask = LVCF_WIDTH;
			lvc.cx = UI_PLAYERLIST_WIDTH - 2;
			ListView_InsertColumn(g_hWndListViewPlayers, 0, &lvc);
		}

		g_hWndGroupBox1 = CreateWindow(WC_BUTTON, LoadStr(L"Players", IDS_PLAYERSLIST), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | BS_GROUPBOX, rcClient.right - UI_PLAYERLIST_WIDTH, 0, UI_PLAYERLIST_WIDTH, rcClient.bottom - UI_SERVERINFO_HEIGHT, hWnd, nullptr, g_hInst, nullptr);
		if (g_hWndGroupBox1)
		{
			SetWindowFont(g_hWndGroupBox1, hFont, FALSE);
		}

		g_hWndGroupBox2 = CreateWindow(WC_BUTTON, LoadStr(L"Server Info", IDS_SERVERINFO), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | BS_GROUPBOX, 0, rcClient.bottom - UI_SERVERINFO_HEIGHT, rcClient.right, 118, hWnd, nullptr, g_hInst, nullptr);
		if (g_hWndGroupBox2)
		{
			SetWindowFont(g_hWndGroupBox2, hFont, FALSE);

			int y = 18;
#define LINE_GAP 20

			HWND hStatic = CreateWindow(WC_STATIC, LoadStr(L"Server Name:", IDS_SERVERNAME_), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, 10, y, 100, 16, g_hWndGroupBox2, nullptr, g_hInst, nullptr);
			if (hStatic) SetWindowFont(hStatic, hFont, FALSE);

			HWND hEdit = CreateWindow(WC_EDIT, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | ES_READONLY, 112, y, 300, 16, g_hWndGroupBox2, (HMENU)1001, g_hInst, nullptr);
			if (hEdit) SetWindowFont(hEdit, hFont, FALSE);
			y += LINE_GAP;

			hStatic = CreateWindow(WC_STATIC, LoadStr(L"Server IP:", IDS_SERVERIP), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, 10, y, 100, 16, g_hWndGroupBox2, nullptr, g_hInst, nullptr);
			if (hStatic) SetWindowFont(hStatic, hFont, FALSE);

			hEdit = CreateWindow(WC_EDIT, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | ES_READONLY, 112, y, 300, 16, g_hWndGroupBox2, (HMENU)1002, g_hInst, nullptr);
			if (hEdit) SetWindowFont(hEdit, hFont, FALSE);
			y += LINE_GAP;

			hStatic = CreateWindow(WC_STATIC, LoadStr(L"Server Players:", IDS_SERVERPLAYERS), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, 10, y, 100, 16, g_hWndGroupBox2, nullptr, g_hInst, nullptr);
			if (hStatic) SetWindowFont(hStatic, hFont, FALSE);

			hEdit = CreateWindow(WC_EDIT, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | ES_READONLY, 112, y, 300, 16, g_hWndGroupBox2, (HMENU)1003, g_hInst, nullptr);
			if (hEdit) SetWindowFont(hEdit, hFont, FALSE);
			y += LINE_GAP;

			hStatic = CreateWindow(WC_STATIC, LoadStr(L"Server Ping:", IDS_SERVERPING), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, 10, y, 100, 16, g_hWndGroupBox2, nullptr, g_hInst, nullptr);
			if (hStatic) SetWindowFont(hStatic, hFont, FALSE);

			hEdit = CreateWindow(WC_EDIT, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | ES_READONLY, 112, y, 300, 16, g_hWndGroupBox2, (HMENU)1004, g_hInst, nullptr);
			if (hEdit) SetWindowFont(hEdit, hFont, FALSE);
			y += LINE_GAP;

			hStatic = CreateWindow(WC_STATIC, LoadStr(L"Server Gamemode:", IDS_SERVERGAMEMODE), WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SS_RIGHT, 10, y, 100, 16, g_hWndGroupBox2, nullptr, g_hInst, nullptr);
			if (hStatic) SetWindowFont(hStatic, hFont, FALSE);

			hEdit = CreateWindow(WC_EDIT, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | ES_READONLY, 112, y, 300, 16, g_hWndGroupBox2, (HMENU)1005, g_hInst, nullptr);
			if (hEdit) SetWindowFont(hEdit, hFont, FALSE);
		}

		g_hWndStatusBar = CreateWindow(STATUSCLASSNAME, nullptr, WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBARS_SIZEGRIP, 0, 0, 0, 0, hWnd, nullptr, g_hInst, nullptr);

		do {
			g_UDPSocket = socket(AF_INET, SOCK_DGRAM, 0);
			if (g_UDPSocket == INVALID_SOCKET)
				break;

			uint32_t timeout = 2000;
			setsockopt(g_UDPSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout));

			struct sockaddr_in bindaddr = { AF_INET };
			if (bind(g_UDPSocket, (sockaddr *)&bindaddr, 16) != NO_ERROR)
			{
				closesocket(g_UDPSocket);
				break;
			}

			if (WSAAsyncSelect(g_UDPSocket, hWnd, WM_SOCKET, FD_READ) == SOCKET_ERROR)
			{
				closesocket(g_UDPSocket);
				break;
			}

			return 0;
		} while (0);
	}
	break;
	case WM_COMMAND:
	{
		int wmId = LOWORD(wParam);
		switch (wmId)
		{
		case IDM_TOOLS_SETTINGS:
			ShowSettings();
			break;
		case IDM_ABOUT:
			DialogBox(g_hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
	}
	break;
	case WM_NOTIFY:
	{
		switch (((LPNMHDR)lParam)->code)
		{
		case TCN_SELCHANGE:
		{
			g_currentTab = TabCtrl_GetCurSel(((LPNMHDR)lParam)->hwndFrom);
			switch (g_currentTab)
			{
			case 0: // Favorites
			case 1: // Internet
			case 2: // Official
			case 3: // Lan
				ListView_DeleteAllItems(g_hWndListViewServers);
				ListView_DeleteAllItems(g_hWndListViewPlayers);
				g_serversList.clear();
				ShowWindow(g_hWndListViewServers, SW_SHOW);
				ShowWindow(g_hWndListViewHistory, SW_HIDE);
				UpdateWindow(g_hWndListViewServers);
				if (g_currentTab == 1 || g_currentTab == 2)
				{
					HWND hDialog = CreateDialog(g_hInst, MAKEINTRESOURCEW(IDD_LOADING), hWnd, nullptr);
					SetWindowPos(hDialog, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
					UpdateWindow(hDialog);

					if (g_serversMasterList)
					{
						delete g_serversMasterList;
						g_serversMasterList = nullptr;
					}

					std::string data;
					data.reserve(2048);

					const char *url;
					if (g_currentTab == 1)
						url = (g_browserSettings.masterlistURL + "/servers").c_str();
					else
						url = (g_browserSettings.masterlistURL + "/official").c_str();
					CURLcode curlRet = CurlRequset(url, data, "VCMP/0.4");
					if (curlRet == CURLE_OK)
					{
						serverMasterList serversList;
						if (ParseJson(data.data(), serversList))
						{
							for (auto it = serversList.begin(); it != serversList.end(); ++it)
							{
								SendQuery(it->address, 'i');
								it->lastPing = GetTickCount();
							}
							g_serversMasterList = new serverMasterList(serversList);
						}
						else
						{
							MessageBox(hWnd, LoadStr(L"Can't parse master list data.", IDS_MASTERLISTDATA), LoadStr(L"Error", IDS_ERROR), MB_ICONWARNING);
						}
					}
					else
					{
						wchar_t message[512];
						swprintf_s(message, LoadStr(L"Can't get information from master list.\n%hs", IDS_MASTERLISTFAILED), curl_easy_strerror(curlRet));
						MessageBox(hWnd, message, LoadStr(L"Error", IDS_ERROR), MB_ICONWARNING);
					}

					DestroyWindow(hDialog);
				}
				else if (g_currentTab == 3)
				{
					BOOL broadcast = TRUE;
					setsockopt(g_UDPSocket, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast));

					for (uint16_t port = 8000; port <= 8200; ++port)
					{
						serverAddress address = { INADDR_BROADCAST, port };
						SendQuery(address, 'i');
					}

					broadcast = FALSE;
					setsockopt(g_UDPSocket, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast));

					lanLastPing = GetTickCount();
				}
				break;
			case 4: // History
				ShowWindow(g_hWndListViewHistory, SW_SHOW);
				ShowWindow(g_hWndListViewServers, SW_HIDE);
				break;
			}
		}
		break;
		case LVN_GETDISPINFO:
		{
			LPNMLVDISPINFOW di = (LPNMLVDISPINFOW)lParam;
			if (di->hdr.hwndFrom == g_hWndListViewServers)
			{
				size_t i = di->item.iItem;
				if (g_serversList.size() > i)
				{
					if (di->item.iSubItem == 0 && di->item.mask & LVIF_IMAGE)
						di->item.iImage = 0;

					if (di->item.mask & LVIF_TEXT)
					{
						switch (di->item.iSubItem)
						{
						case 0: // Icon
							break;
						case 1: // Server Name
							if (di->item.cchTextMax > 0 && di->item.pszText)
							{
								MultiByteToWideChar(CP_ACP, 0, g_serversList[i].info.serverName.c_str(), -1, di->item.pszText, di->item.cchTextMax);
							}
							break;
						case 2: // Ping
						{
							uint32_t ping = g_serversList[i].lastRecv - g_serversList[i].lastPing[1];
							_itow_s(ping, di->item.pszText, di->item.cchTextMax, 10);
						}
						break;
						case 3: // Players
							swprintf_s(di->item.pszText, di->item.cchTextMax, L"%hu/%hu", g_serversList[i].info.players, g_serversList[i].info.maxPlayers);
							break;
						case 4: // Version
						{
							MultiByteToWideChar(CP_ACP, 0, g_serversList[i].info.versionName, -1, di->item.pszText, di->item.cchTextMax);
						}
						break;
						case 5: // Gamemode
						{
							MultiByteToWideChar(CP_ACP, 0, g_serversList[i].info.gameMode.c_str(), -1, di->item.pszText, di->item.cchTextMax);
						}
						break;
						case 6: // Map name
						{
							MultiByteToWideChar(CP_ACP, 0, g_serversList[i].info.mapName.c_str(), -1, di->item.pszText, di->item.cchTextMax);
						}
						break;
						}
					}
				}
			}
			else if (di->hdr.hwndFrom == g_hWndListViewHistory) // FIXME
			{

			}
			else if (di->hdr.hwndFrom == g_hWndListViewPlayers)
			{
				size_t i = ListView_GetSelectionMark(g_hWndListViewServers);
				if (g_serversList.size() > i)
				{
					serverPlayers &players = g_serversList[i].players;

					size_t j = di->item.iItem;
					if (players.size() > j)
					{
						if (di->item.mask & LVIF_TEXT)
						{
							MultiByteToWideChar(CP_ACP, 0, players[j].name, -1, di->item.pszText, di->item.cchTextMax);
						}
					}
				}
			}
		}
		break;
		case NM_CUSTOMDRAW:
		{
			LPNMLVCUSTOMDRAW nmcd = (LPNMLVCUSTOMDRAW)lParam;
			if (nmcd->nmcd.hdr.hwndFrom == g_hWndListViewServers)
			{
				switch (nmcd->nmcd.dwDrawStage)
				{
				case CDDS_PREPAINT:
					return CDRF_NOTIFYITEMDRAW;
				case CDDS_ITEMPREPAINT:
				{
					COLORREF crText;
					size_t i = nmcd->nmcd.dwItemSpec;
					if (g_serversList.size() > i && g_serversList[i].isOfficial)
						crText = g_browserSettings.officialColor;
					else
						crText = 0;

					nmcd->clrText = crText;
					return CDRF_DODEFAULT;
				}
				}
			}
		}
		break;
		case LVN_ITEMCHANGED:
		{
			LPNMITEMACTIVATE nmitem = (LPNMITEMACTIVATE)lParam;
			if (nmitem->hdr.hwndFrom == g_hWndListViewServers)
			{
				size_t i = nmitem->iItem;
				if (i != -1 && g_serversList.size() > i)
				{
					if (g_serversList[i].info.players == 0)
						ListView_DeleteAllItems(g_hWndListViewPlayers);

					std::wstring wstr;

					ConvertCharset(g_serversList[i].info.serverName.c_str(), wstr);
					SetDlgItemText(g_hWndGroupBox2, 1001, wstr.c_str()); // Server Name

					wchar_t ipstr[22];
					char *ip = (char *)&(g_serversList[i].address.ip);
					swprintf_s(ipstr, L"%hhu.%hhu.%hhu.%hhu:%hu", ip[0], ip[1], ip[2], ip[3], g_serversList[i].address.port);
					SetDlgItemText(g_hWndGroupBox2, 1002, ipstr); // Server IP

					wchar_t playersstr[12];
					swprintf_s(playersstr, L"%hu/%hu", g_serversList[i].info.players, g_serversList[i].info.maxPlayers);
					SetDlgItemText(g_hWndGroupBox2, 1003, playersstr); // Server Players

					wchar_t pingsstr[12];
					uint32_t ping = g_serversList[i].lastRecv - g_serversList[i].lastPing[1];
					_itow_s(ping, pingsstr, 10);
					SetDlgItemText(g_hWndGroupBox2, 1004, pingsstr); // Server Ping

					ConvertCharset(g_serversList[i].info.gameMode.c_str(), wstr);
					SetDlgItemText(g_hWndGroupBox2, 1005, wstr.c_str()); // Server Gamemode

					SendQuery(g_serversList[i].address, 'i');
					SendQuery(g_serversList[i].address, 'c');
					g_serversList[i].lastPing[0] = GetTickCount();
				}
				else
				{
					ListView_DeleteAllItems(g_hWndListViewPlayers);
					for (int i = 1001; i <= 1005; ++i)
						SetDlgItemText(g_hWndGroupBox2, i, nullptr);
				}
			}
		}
		break;
		case LVN_ITEMACTIVATE:
		{
			LPNMITEMACTIVATE nmia = (LPNMITEMACTIVATE)lParam;
			if (nmia->hdr.hwndFrom == g_hWndListViewServers)
			{
				size_t i = nmia->iItem;
				if (i != -1 && g_serversList.size() > i)
				{
					char ipstr[16];
					char *ip = (char *)&(g_serversList[i].address.ip);
					snprintf(ipstr, sizeof(ipstr), "%hhu.%hhu.%hhu.%hhu", ip[0], ip[1], ip[2], ip[3]);
					char vcmpDll[MAX_PATH];
					snprintf(vcmpDll, sizeof(vcmpDll), "%ls%s\\vcmp-game.dll", g_exePath, g_serversList[i].info.versionName);
					LaunchVCMP(ipstr, g_serversList[i].address.port, g_browserSettings.playerName, nullptr, g_browserSettings.gamePath, vcmpDll);
				}
			}
		}
		break;
		}
	}
	break;
	case WM_SIZE:
	{
		int clientWidth = GET_X_LPARAM(lParam), clientHeight = GET_Y_LPARAM(lParam);
		SetWindowPos(g_hWndTab, 0, 0, 0, clientWidth - UI_PLAYERLIST_WIDTH, clientHeight - UI_SERVERINFO_HEIGHT, SWP_NOZORDER);
		SetWindowPos(g_hWndListViewServers, 0, 1, 21, clientWidth - UI_PLAYERLIST_WIDTH - 4, clientHeight - UI_SERVERINFO_HEIGHT - 21 - 2, SWP_NOZORDER);
		SetWindowPos(g_hWndListViewHistory, 0, 1, 21, clientWidth - UI_PLAYERLIST_WIDTH - 4, clientHeight - UI_SERVERINFO_HEIGHT - 21 - 2, SWP_NOZORDER);
		SetWindowPos(g_hWndGroupBox1, 0, clientWidth - UI_PLAYERLIST_WIDTH, 0, UI_PLAYERLIST_WIDTH, clientHeight - UI_SERVERINFO_HEIGHT, SWP_NOZORDER);
		SetWindowPos(g_hWndListViewPlayers, 0, clientWidth - UI_PLAYERLIST_WIDTH + 1, 18, UI_PLAYERLIST_WIDTH - 2, clientHeight - UI_SERVERINFO_HEIGHT - 18 - 2, SWP_NOZORDER);
		SetWindowPos(g_hWndGroupBox2, 0, 0, clientHeight - UI_SERVERINFO_HEIGHT, clientWidth, 118, SWP_NOZORDER);
		SendMessage(g_hWndStatusBar, WM_SIZE, 0, 0);
	}
	break;
	case WM_GETMINMAXINFO:
		((LPMINMAXINFO)lParam)->ptMinTrackSize = { 750, 500 };
		break;
	case WM_DESTROY:
		if (_hFont)
			DeleteObject(_hFont);
		PostQuitMessage(0);
		break;
	case WM_SOCKET:
	{
		if (WSAGETSELECTEVENT(lParam) == FD_READ)
		{
			char *recvBuf = (char *)calloc(1024, sizeof(char));
			if (recvBuf)
			{
				struct sockaddr_in recvAddr;
				int addrLen = sizeof(recvAddr);
				int recvLen = recvfrom(g_UDPSocket, recvBuf, 1024, 0, (sockaddr *)&recvAddr, &addrLen);
				if (recvLen != -1 && recvLen >= 11)
				{
					if (recvLen > 1024)
						recvLen = 1024;

					if (*(int *)recvBuf == 0x3430504D) // MP04
					{
						char opcode = recvBuf[10];
						if (opcode == 'i' || opcode == 'c')
						{
							uint32_t ip = recvAddr.sin_addr.s_addr;
							uint16_t port = ntohs(recvAddr.sin_port);

							bool found = false;
							serverMasterListInfo masterInfo;
							if (g_currentTab == 1 || g_currentTab == 2)
							{
								for (auto it = g_serversMasterList->begin(); it != g_serversMasterList->end(); ++it)
								{
									if (it->address.ip == ip && it->address.port == port)
									{
										found = true;
										masterInfo = *it;
										break;
									}
								}
							}
							else if (g_currentTab == 3) // Lan
							{
								found = true;
								masterInfo.address = { ip, port };
								masterInfo.isOfficial = false;
								masterInfo.lastPing = lanLastPing;
							}

							if (found)
							{
								switch (opcode)
								{
								case 'i':
								{
									serverInfo info;
									if (GetServerInfo(recvBuf, recvLen, info))
									{
										bool inList = false;
										for (auto it = g_serversList.begin(); it != g_serversList.end(); ++it)
										{
											if (it->address.ip == ip && it->address.port == port)
											{
												inList = true;
												it->lastRecv = GetTickCount();
												it->lastPing[1] = it->lastPing[0];
												it->info = info;
												auto i = it - g_serversList.begin();
												ListView_Update(g_hWndListViewServers, i);
												break;
											}
										}
										if (!inList)
										{
											serverAllInfo allInfo;
											allInfo.address = masterInfo.address;
											allInfo.info = info;
											allInfo.isOfficial = masterInfo.isOfficial;
											allInfo.lastPing[0] = masterInfo.lastPing;
											allInfo.lastPing[1] = masterInfo.lastPing;
											allInfo.lastRecv = GetTickCount();
											g_serversList.push_back(allInfo);

											LVITEM lvi = { 0 };
											ListView_InsertItem(g_hWndListViewServers, &lvi);
										}
									}
								}
								break;
								case 'c':
								{
									serverPlayers players;
									if (GetServerPlayers(recvBuf, recvLen, players))
									{
										for (auto it = g_serversList.begin(); it != g_serversList.end(); ++it)
										{
											if (it->address.ip == ip && it->address.port == port)
											{
												it->lastRecv = GetTickCount();
												it->lastPing[1] = it->lastPing[0];
												it->players = players;
												auto i = it - g_serversList.begin();
												ListView_SetItemCount(g_hWndListViewPlayers, players.size());
												break;
											}
										}
									}
								}
								break;
								}
							}
						}
					}
				}
				free(recvBuf);
			}
		}
	}
	break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
Пример #15
0
	VarValue Parse(istream& is, Encoding *enc) override {
		String full;
		for (string s; getline(is, s);)
			full += s;
		return ParseJson(full);
	}