UUID CreateLocalUUID() //-------------------- { #if _WIN32_WINNT >= 0x0501 // Available since Win2000, but we check for WinXP in order to not use this // function in Win32old builds. It is not available on some non-fully // patched Win98SE installs in the wild. UUID uuid = UUID(); RPC_STATUS status = ::UuidCreateSequential(&uuid); if(status != RPC_S_OK && status != RPC_S_UUID_LOCAL_ONLY) { return UUID(); } return uuid; #else // Fallback to ::UuidCreate is safe as ::UuidCreateSequential is only a // tiny performance optimization. return CreateUUID(); #endif }
int callback_eqemu(libwebsocket_context *context, libwebsocket *wsi, libwebsocket_callback_reasons reason, void *user, void *in, size_t len) { per_session_data_eqemu *session = (per_session_data_eqemu*)user; switch (reason) { case LWS_CALLBACK_ESTABLISHED: session->uuid = CreateUUID(); session->send_queue = new std::list<std::string>(); sessions[session->uuid] = session; break; case LWS_CALLBACK_RECEIVE: { //recv and parse commands here if(len < 1) break; rapidjson::Document document; if(document.Parse((const char*)in).HasParseError()) { WriteWebCallResponseString(session, document, "Malformed JSON data", true, true); break; } std::string method; if(document.HasMember("method") && !document["method"].Empty() && document["method"].IsString()) { method = document["method"].GetString(); } if(method.length() == 0) { //No function called, toss this message WriteWebCallResponseString(session, document, "No method specified", true); break; } int status = CheckTokenAuthorization(session); if (status == 0) { //check func call against functions that dont req auth if (unauthorized_methods.count(method) == 0) { WriteWebCallResponseString(session, document, "No suitable method found: " + method, true); break; } auto call_func = unauthorized_methods[method]; call_func(session, document, method); } else if(status > 0) { //check func call against functions that req auth if (authorized_methods.count(method) == 0) { WriteWebCallResponseString(session, document, "No suitable method found: " + method, true); break; } //check status level auto iter = authorized_methods.find(method); if(iter->second.first > status) { WriteWebCallResponseString(session, document, "Method " + method + " requires status " + std::to_string((long)iter->second.first), true); break; } auto call_func = iter->second.second; call_func(session, document, method); } break; } case LWS_CALLBACK_SERVER_WRITEABLE: { std::vector<char> out_message; for (auto iter = session->send_queue->begin(); iter != session->send_queue->end(); ++iter) { out_message.resize((*iter).size() + LWS_SEND_BUFFER_PRE_PADDING + LWS_SEND_BUFFER_POST_PADDING + 1); memset(&out_message[0], 0, (*iter).size() + LWS_SEND_BUFFER_PRE_PADDING + LWS_SEND_BUFFER_POST_PADDING + 1); memcpy(&out_message[LWS_SEND_BUFFER_PRE_PADDING], &(*iter)[0], (*iter).size()); int n = libwebsocket_write(wsi, (unsigned char*)&out_message[LWS_SEND_BUFFER_PRE_PADDING], (*iter).size(), LWS_WRITE_TEXT); if(n < (*iter).size()) { return -1; } } session->send_queue->clear(); break; } case LWS_CALLBACK_PROTOCOL_DESTROY: //clean up sessions here safe_delete(session->send_queue); break; case LWS_CALLBACK_CLOSED: //Session closed but perhaps not yet destroyed, we still don't want to track it though. sessions.erase(session->uuid); safe_delete(session->send_queue); session->uuid.clear(); break; default: break; }; return 0; }