static void se_refreshSceneLightStatus(JNIEnv* env, jobject obj) { jstring sceneName = (jstring)env->GetObjectField(obj, sceneNameID); const char* sceneName8 = env->GetStringUTFChars(sceneName, 0); SE_Scene* scene = findScene(sceneName8); if(scene) { scene->refreshSceneLightStatus(); } env->ReleaseStringUTFChars(sceneName, sceneName8); }
static void se_setLowestBrightness(JNIEnv* env, jobject obj, jfloat lowestBrightnesss) { jstring sceneName = (jstring)env->GetObjectField(obj, sceneNameID); const char* sceneName8 = env->GetStringUTFChars(sceneName, 0); SE_Scene* scene = findScene(sceneName8); if(scene) { scene->setLowestEnvBrightness(lowestBrightnesss); } env->ReleaseStringUTFChars(sceneName, sceneName8); }
/** *set scene manager * *@max_depth the max depth of octree scene manager *@type the type of scene manager */ static void se_setSceneDepthType(JNIEnv* env, jobject obj, jint max_depth, jint type) { jstring sceneName = (jstring)env->GetObjectField(obj, sceneNameID); const char* sceneName8 = env->GetStringUTFChars(sceneName, 0); SE_Scene* scene = findScene(sceneName8); if(scene) { scene->setSceneManagerDepthType(max_depth, type); } env->ReleaseStringUTFChars(sceneName, sceneName8); }
void GrimEngine::setSceneLock(const char *name, bool lockStatus) { Scene *scene = findScene(name); if (!scene) { if (gDebugLevel == DEBUG_WARN || gDebugLevel == DEBUG_ALL) warning("Scene object '%s' not found in list", name); return; } // Change the locking status scene->_locked = lockStatus; }
static void se_removeAllLight(JNIEnv* env, jobject obj, jint lighttype) { jstring sceneName = (jstring)env->GetObjectField(obj, sceneNameID); const char* sceneName8 = env->GetStringUTFChars(sceneName, 0); SE_Scene* scene = findScene(sceneName8); if(scene) { scene->removeAllLights(); } env->ReleaseStringUTFChars(sceneName, sceneName8); }
static void se_setIsTranslucent(JNIEnv* env, jobject obj, jboolean translucent) { jstring sceneName = (jstring)env->GetObjectField(obj, sceneNameID); const char* sceneName8 = env->GetStringUTFChars(sceneName, 0); SE_Scene* scene = findScene(sceneName8); if (scene) { scene->setIsTranslucent(translucent); } env->ReleaseStringUTFChars(sceneName, sceneName8); }
bool Pony::tryWearItem(quint8 invSlot) { //win.logMessage("Invslot is "+QString().setNum(invSlot)); uint32_t id = -1; uint32_t itemSlots; for (int i=0; i<inv.size(); i++) { if (inv[i].index == invSlot) { id = inv[i].id; itemSlots = win.wearablePositionsMap[id]; if (wornSlots & itemSlots) { win.logMessage("Can't wear item: slots occupied", udpTag); return false; } sendDeleteItemRPC(owner,inv[i].index,1); if (inv[i].amount>1) inv[i].amount--; else inv.removeAt(i); break; } } if (id == (uint32_t)-1) { // wtf? win.logMessage("Index not found", sysTag); return false; } wornSlots |= itemSlots; WearableItem item; item.id = id; item.index = wearablePositionsToSlot(itemSlots); //win.logMessage("Wearing at slot "+QString().setNum(item.index)); worn << item; sendWearItemRPC(owner, item); Scene* scene = findScene(sceneName); if (scene->name.isEmpty()) win.logMessage("UDP: Can't find the scene for wearItem RPC, aborting", udpTag); else { for (Player* dest : scene->players) if (dest->pony.netviewId != netviewId) sendWearItemRPC(this, dest, item); } return true; }
static void se_removeLightFromScene(JNIEnv* env, jobject obj, jstring lightName) { jstring sceneName = (jstring)env->GetObjectField(obj, sceneNameID); const char* sceneName8 = env->GetStringUTFChars(sceneName, 0); SE_Scene* scene = findScene(sceneName8); if(scene) { const char* lightName8 = env->GetStringUTFChars(lightName, 0); scene->removeLight(lightName8); env->ReleaseStringUTFChars(lightName, lightName8); } env->ReleaseStringUTFChars(sceneName, sceneName8); }
void Pony::takeDamage(unsigned amount) { if (health <= (float)amount/defense) kill(); else { health -= (float)amount/defense; Scene* scene = findScene(sceneName); for (Player* player : scene->players) { sendSetStatRPC(player, netviewId, 1, health); } } }
void Pony::kill() { health = 0; dead = true; Scene* scene = findScene(sceneName); for (Player* player : scene->players) { if (player->pony.netviewId != netviewId) sendNetviewRemove(player, netviewId, NetviewRemoveReasonKill); } respawn(); }
static void se_setRoot_II(JNIEnv* env, jobject obj, jint object) { if (object > 0) { jstring sceneName = (jstring)env->GetObjectField(obj, sceneNameID); const char* sceneName8 = env->GetStringUTFChars(sceneName, 0); SE_Scene* scene = findScene(sceneName8); if (scene) { scene->setRoot((SE_Spatial*)object); } env->ReleaseStringUTFChars(sceneName, sceneName8); } }
void sendEntitiesList(Player *player) { levelLoadMutex.lock(); // Protect player->inGame if (player->inGame == 0) // Not yet in game, send player's ponies list (Characters scene) { levelLoadMutex.unlock(); #if DEBUG_LOG win.logMessage("UDP: Sending ponies list"); #endif sendPonies(player); return; } else if (player->inGame > 1) // Not supposed to happen, let's do it anyway { //levelLoadMutex.unlock(); win.logMessage(QString("UDP: Entities list already sent to ")+QString().setNum(player->pony.netviewId) +", resending anyway"); //return; } else // Loading finished, sending entities list win.logMessage(QString("UDP: Sending entities list to ")+QString().setNum(player->pony.netviewId)); Scene* scene = findScene(player->pony.sceneName); // Spawn all the players on the client for (int i=0; i<scene->players.size(); i++) sendNetviewInstantiate(&scene->players[i]->pony, player); // Send npcs for (int i=0; i<win.npcs.size(); i++) if (win.npcs[i]->sceneName.toLower() == player->pony.sceneName.toLower()) { #if DEBUG_LOG win.logMessage("UDP: Sending NPC "+win.npcs[i]->name); #endif sendNetviewInstantiate(win.npcs[i], player); } // Spawn some mobs in Zecoras if (scene->name.toLower() == "zecoras") { sendNetviewInstantiate(player,"mobs/dragon", win.getNewId(), win.getNewNetviewId(), {-33.0408, 0.000425577, 101.766}, {0,-1,0,1}); } player->inGame = 2; levelLoadMutex.unlock(); // Send stats of the client's pony sendSetMaxStatRPC(player, 0, 100); sendSetStatRPC(player, 0, 100); sendSetMaxStatRPC(player, 1, 100); sendSetStatRPC(player, 1, 100); }
static void se_createScene(JNIEnv* env, jobject obj) { jstring sceneName = (jstring)env->GetObjectField(obj, sceneNameID); const char* sceneName8 = env->GetStringUTFChars(sceneName, 0); SE_Scene* scene = findScene(sceneName8); if (!scene) { scene = new SE_Scene(sceneName8); SE_Application::getInstance()->getSceneManager()->pushBack(SE_FRAMEBUFFER_SCENE, scene); SE_Camera* camera = new SE_Camera(); scene->inflate("assets/base/scene_resource.xml"); scene->setCamera(camera); } env->ReleaseStringUTFChars(sceneName, sceneName8); }
static void se_setVisibility(JNIEnv* env, jobject obj, jboolean visibility) { jstring sceneName = (jstring)env->GetObjectField(obj, sceneNameID); const char* sceneName8 = env->GetStringUTFChars(sceneName, 0); SE_Scene* scene = findScene(sceneName8); if (scene) { if (visibility) { scene->setVisibility(SE_VISIBLE); } else { scene->setVisibility(SE_NOVISIBLE); } } env->ReleaseStringUTFChars(sceneName, sceneName8); }
static void se_changeSceneShader(JNIEnv* env, jobject obj,jstring shaderName,jstring renderName) { jstring sceneName = (jstring)env->GetObjectField(obj, sceneNameID); const char* sceneName8 = env->GetStringUTFChars(sceneName, 0); SE_Scene* scene = findScene(sceneName8); if(scene) { const char* shadername = env->GetStringUTFChars(shaderName, 0); const char* rendername = env->GetStringUTFChars(renderName, 0); scene->changeSceneShader(shadername,rendername); env->ReleaseStringUTFChars(shaderName, shadername); env->ReleaseStringUTFChars(renderName, rendername); } env->ReleaseStringUTFChars(sceneName, sceneName8); }
static void se_setNeedDraw(JNIEnv* env, jobject obj, jboolean need) { jstring sceneName = (jstring)env->GetObjectField(obj, sceneNameID); const char* sceneName8 = env->GetStringUTFChars(sceneName, 0); if (need) { SE_Scene* scene = SE_Application::getInstance()->getSceneManager()->getSceneFromRemovedList(SE_FRAMEBUFFER_SCENE, sceneName8, true); if (scene) { SE_Application::getInstance()->getSceneManager()->pushBack(SE_FRAMEBUFFER_SCENE, scene); } } else { SE_Scene* scene = findScene(sceneName8); if (scene) { SE_Application::getInstance()->getSceneManager()->removeScene(scene, false); } } env->ReleaseStringUTFChars(sceneName, sceneName8); }
static void se_updateSceneLightPos(JNIEnv* env, jobject obj,jstring lightName,jfloatArray lightpos) { #if 0 jstring sceneName = (jstring)env->GetObjectField(obj, sceneNameID); const char* sceneName8 = env->GetStringUTFChars(sceneName, 0); SE_Scene* scene = findScene(sceneName8); const char* sceneLightName8 = env->GetStringUTFChars(lightName, 0); if(scene) { float* lpos = env->GetFloatArrayElements(lightpos, 0); SE_Vector3f pos = SE_Vector3f(lpos[0],lpos[1],lpos[2]); //scene->updateSceneLightPos(pos,sceneLightName8); env->ReleaseFloatArrayElements(lightpos, lpos, 0); } env->ReleaseStringUTFChars(sceneName, sceneName8); env->ReleaseStringUTFChars(sceneName, sceneLightName8); #endif }
static void se_updateSceneLightDir(JNIEnv* env, jobject obj, jstring lightName,jfloatArray lightdir) { #if 0 jstring sceneName = (jstring)env->GetObjectField(obj, sceneNameID); const char* sceneName8 = env->GetStringUTFChars(sceneName, 0); SE_Scene* scene = findScene(sceneName8); const char* sceneLightName8 = env->GetStringUTFChars(lightName, 0); if(scene) { float* ldir = env->GetFloatArrayElements(lightdir, 0); SE_Vector3f dir = SE_Vector3f(ldir[0],ldir[1],ldir[2]); scene->updateSceneLightDir(dir,sceneLightName8); env->ReleaseFloatArrayElements(lightdir, ldir, 0); } env->ReleaseStringUTFChars(sceneName, sceneName8); env->ReleaseStringUTFChars(sceneName, sceneLightName8); #endif }
static void se_updateSceneLightSpotData(JNIEnv* env, jobject obj, jstring lightName,jfloatArray spotlightdata) { #if 0 jstring sceneName = (jstring)env->GetObjectField(obj, sceneNameID); const char* sceneName8 = env->GetStringUTFChars(sceneName, 0); SE_Scene* scene = findScene(sceneName8); const char* sceneLightName8 = env->GetStringUTFChars(lightName, 0); if(scene) { float* lspotdata = env->GetFloatArrayElements(spotlightdata, 0); SE_Vector4f spotdata = SE_Vector4f(lspotdata[0],lspotdata[1],lspotdata[2],lspotdata[3]); scene->updateSceneLightSpotData(spotdata,sceneLightName8); env->ReleaseFloatArrayElements(spotlightdata, lspotdata, 0); } env->ReleaseStringUTFChars(sceneName, sceneName8); env->ReleaseStringUTFChars(sceneName, sceneLightName8); #endif }
void GrimEngine::setScene(const char *name) { Scene *scene = findScene(name); Scene *lastScene = _currScene; // If the scene already exists then use the existing data if (scene) { setScene(scene); return; } Block *b = g_resourceloader->getFileBlock(name); if (!b) warning("Could not find scene file %s", name); _currScene = new Scene(name, b->data(), b->len()); registerScene(_currScene); _currScene->setSoundParameters(20, 127); // should delete the old scene after creating the new one if (lastScene && !lastScene->_locked) { removeScene(lastScene); delete lastScene; } delete b; }
void sendEntitiesList(Player *player) { levelLoadMutex.lock(); // Protect player->inGame if (player->inGame == 0) // Not yet in game, send player's ponies list (Characters scene) { levelLoadMutex.unlock(); sendPonies(player); return; } else if (player->inGame > 1) // Not supposed to happen, let's do it anyway { //levelLoadMutex.unlock(); win.logMessage(QString("UDP: Entities list already sent to ")+QString().setNum(player->pony.netviewId) +", resending anyway"); //return; } else // Loading finished, sending entities list win.logMessage(QString("UDP: Sending entities list to ")+QString().setNum(player->pony.netviewId)); Scene* scene = findScene(player->pony.sceneName); // Spawn all the players on the client for (int i=0; i<scene->players.size(); i++) sendNetviewInstantiate(scene->players[i], player); /// SEND DONUT STEEL (in front of the mirror) if (scene->name == "RaritysBoutique") { win.logMessage(QString("UDP: Sending Donut Steel to ")+QString().setNum(player->pony.netviewId)); sendNetviewInstantiate(player,"PlayerBase",0,0,UVector(24.7333,-1.16802,-51.7106), UQuaternion(0,-0.25,0,1)); } player->inGame = 2; levelLoadMutex.unlock(); // Send stats of the client's pony sendSetMaxStatRPC(player, 0, 100); sendSetStatRPC(player, 0, 100); sendSetMaxStatRPC(player, 1, 100); sendSetStatRPC(player, 1, 100); }
// Processes the commands entered directly in the server, not the chat messages void Widget::sendCmdLine() { if (!enableGameServer) { logMessage(QObject::tr("This is not a game server, commands are disabled")); return; } QString str = ui->cmdLine->text(); if (str == "clear") { ui->log->clear(); return; } else if (str == "stop") { delete this; return; } else if (str == "listTcpPlayers") { for (int i=0; i<tcpPlayers.size(); i++) { Player* p = tcpPlayers[i]; logMessage(p->name+" "+p->IP+":"+QString().setNum(p->port)); } return; } else if (str.startsWith("setPeer")) { if (udpPlayers.size() == 1) { cmdPeer = udpPlayers[0]; QString peerName = cmdPeer->IP + " " + QString().setNum(cmdPeer->port); logMessage(QObject::tr("UDP: Peer set to %1").arg(peerName)); return; } str = str.right(str.size()-8); QStringList args = str.split(':'); bool ok; if (args.size() != 2) { if (args.size() != 1) { logMessage(QObject::tr("UDP: setPeer takes a pony id or ip:port combination")); return; } quint16 id = args[0].toUInt(&ok); if (!ok) { logMessage(QObject::tr("UDP: setPeer takes a pony id as argument")); return; } for (int i=0; i<udpPlayers.size();i++) { if (udpPlayers[i]->pony.id == id) { cmdPeer = Player::findPlayer(udpPlayers,udpPlayers[i]->IP, udpPlayers[i]->port); logMessage(QObject::tr("UDP: Peer set to %1").arg(udpPlayers[i]->pony.name)); return; } } logMessage(QObject::tr("UDP: Peer not found (id %1)").arg(args[0])); return; } quint16 port = args[1].toUInt(&ok); if (!ok) { logMessage(QObject::tr("UDP: setPeer takes a port as argument")); return; } cmdPeer = Player::findPlayer(udpPlayers,args[0], port); if (cmdPeer->IP!="") logMessage(QObject::tr("UDP: Peer set to %1").arg(str)); else logMessage(QObject::tr("UDP: Peer not found (%1)").arg(str)); return; } else if (str.startsWith("listPeers")) { if (str.size()<=10) { for (int i=0; i<win.udpPlayers.size();i++) win.logMessage(QString().setNum(win.udpPlayers[i]->pony.id) +" ("+QString().setNum(win.udpPlayers[i]->pony.netviewId)+")" +" "+win.udpPlayers[i]->pony.name +" "+win.udpPlayers[i]->IP +":"+QString().setNum(win.udpPlayers[i]->port) +" "+QString().setNum((int)timestampNow()-win.udpPlayers[i]->lastPingTime)+"s"); return; } str = str.right(str.size()-10); Scene* scene = findScene(str); if (scene->name.isEmpty()) win.logMessage(QObject::tr("Can't find scene")); else for (int i=0; i<scene->players.size();i++) win.logMessage(win.udpPlayers[i]->IP +":"+QString().setNum(win.udpPlayers[i]->port) +" "+QString().setNum((int)timestampNow()-win.udpPlayers[i]->lastPingTime)+"s"); return; } else if (str.startsWith("listVortexes")) { for (int i=0; i<scenes.size(); i++) { win.logMessage("Scene "+scenes[i].name); for (int j=0; j<scenes[i].vortexes.size(); j++) win.logMessage("Vortex "+QString().setNum(scenes[i].vortexes[j].id) +" to "+scenes[i].vortexes[j].destName+" " +QString().setNum(scenes[i].vortexes[j].destPos.x)+" " +QString().setNum(scenes[i].vortexes[j].destPos.y)+" " +QString().setNum(scenes[i].vortexes[j].destPos.z)); } return; } else if (str.startsWith("sync")) { win.logMessage(QObject::tr("UDP: Syncing manually")); sync.doSync(); return; } // DEBUG global commands from now on else if (str==("dbgStressLoad")) { // Send all the players to the GemMines at the same time for (int i=0; i<udpPlayers.size(); i++) sendLoadSceneRPC(udpPlayers[i], "GemMines"); return; } else if (str.startsWith("dbgStressLoad")) { str = str.mid(14); // Send all the players to the given scene at the same time for (int i=0; i<udpPlayers.size(); i++) sendLoadSceneRPC(udpPlayers[i], str); return; } else if (str.startsWith("tele")) { str = str.right(str.size()-5); QStringList args = str.split(' '); if (args.size() != 2) { logStatusMessage(QObject::tr("Error: Usage is tele ponyIdToMove destinationPonyId")); return; } bool ok; bool ok1; bool ok2 = false; quint16 sourceID = args[0].toUInt(&ok); quint16 destID = args[1].toUInt(&ok1); Player* sourcePeer; if (!ok && !ok1) { logStatusMessage(QObject::tr("Error: Usage is tele ponyIdToMove destinationPonyId")); return; } for (int i=0; i<udpPlayers.size();i++) { if (udpPlayers[i]->pony.id == sourceID) { sourcePeer = udpPlayers[i]; ok2 = true; break; } } if (!ok2) { logStatusMessage(QObject::tr("Error: Source peer does not exist!")); return; } for (int i=0; i<udpPlayers.size();i++) { if (udpPlayers[i]->pony.id == destID) { logMessage(QObject::tr("UDP: Teleported %1 to %2").arg(sourcePeer->pony.name,udpPlayers[i]->pony.name)); if (udpPlayers[i]->pony.sceneName.toLower() != sourcePeer->pony.sceneName.toLower()) sendLoadSceneRPC(sourcePeer, udpPlayers[i]->pony.sceneName, udpPlayers[i]->pony.pos); else sendMove(sourcePeer, udpPlayers[i]->pony.pos.x, udpPlayers[i]->pony.pos.y, udpPlayers[i]->pony.pos.z); return; } } logMessage(QObject::tr("Error: Destination peer does not exist!")); } if (cmdPeer->IP=="") { logMessage(QObject::tr("Select a peer first with setPeer/listPeers")); return; } else // Refresh peer info { cmdPeer = Player::findPlayer(udpPlayers,cmdPeer->IP, cmdPeer->port); if (cmdPeer->IP=="") { logMessage(QObject::tr("UDP: Peer not found")); return; } } // User commands from now on (requires setPeer) if (str.startsWith("disconnect")) { logMessage(QObject::tr("UDP: Disconnecting")); sendMessage(cmdPeer,MsgDisconnect, "Connection closed by the server admin"); Player::disconnectPlayerCleanup(cmdPeer); // Save game and remove the player } else if (str.startsWith("load")) { str = str.mid(5); sendLoadSceneRPC(cmdPeer, str); } else if (str.startsWith("getPos")) { logMessage(QObject::tr("Pos : ","Short for position") + QString().setNum(cmdPeer->pony.pos.x) + " " + QString().setNum(cmdPeer->pony.pos.y) + " " + QString().setNum(cmdPeer->pony.pos.z)); } else if (str.startsWith("getRot")) { logMessage(QObject::tr("Rot : x=","Short for rotation") + QString().setNum(cmdPeer->pony.rot.x) + ", y=" + QString().setNum(cmdPeer->pony.rot.y) + ", z=" + QString().setNum(cmdPeer->pony.rot.z) + ", w=" + QString().setNum(cmdPeer->pony.rot.w)); } else if (str.startsWith("getPonyData")) { logMessage("ponyData : "+cmdPeer->pony.ponyData.toBase64()); } else if (str.startsWith("sendPonies")) { sendPonies(cmdPeer); } else if (str.startsWith("sendUtils3")) { logMessage(QObject::tr("UDP: Sending Utils3 request")); QByteArray data(1,3); sendMessage(cmdPeer,MsgUserReliableOrdered6,data); } else if (str.startsWith("setPlayerId")) { str = str.right(str.size()-12); QByteArray data(3,4); bool ok; unsigned id = str.toUInt(&ok); if (ok) { logMessage(QObject::tr("UDP: Sending setPlayerId request")); data[1]=(quint8)(id&0xFF); data[2]=(quint8)((id >> 8)&0xFF); sendMessage(cmdPeer,MsgUserReliableOrdered6,data); } else
CzScene* CzApp::findScene(const char* name) { return findScene(CzString::CalculateHash(name)); }
void receiveChatMessage(QByteArray msg, Player* player) { QString txt = dataToString(msg.mid(7)); QString author = player->pony.name; //win.logMessage("Chat "+author+":"+txt); if (txt.startsWith("/stuck") || txt.startsWith("unstuck me")) { sendLoadSceneRPC(player, player->pony.sceneName); } else if (txt == ":commands") { sendChatMessage(player, "<span color=\"yellow\">List of Commands:</span><br /><em>:roll</em><br /><span color=\"yellow\">Rolls a random number between 00 and 99</span><br /><em>:msg player message</em><br /><span color=\"yellow\">Sends a private message to a player</span><br /><em>:names</em><br /><span color=\"yellow\">Lists all players on the server</span><br /><em>:me action</em><br /><span color=\"yellow\">States your current action</span><br /><em>:tp location</em><br /><span color=\"yellow\">Teleports your pony to the specified region</span>", "[Server]", ChatLocal); } else if (txt.startsWith(":msg")) { if(txt.count(" ") < 2) sendChatMessage(player, ":msg<br /><span color=\"yellow\">Usage:</span><br /><em>:msg player message</em><br /><span color=\"yellow\">Player names are case-insensitive, ignore spaces and you do not need to type out their full name.</span>", author, ChatLocal); else { for (int i=0; i<win.udpPlayers.size(); i++) { if (win.udpPlayers[i]->inGame>=2 && win.udpPlayers[i]->pony.name.toLower().remove(" ").startsWith(txt.toLower().section(" ", 1, 1))) { txt = txt.remove(0, txt.indexOf(" ", 5) + 1); sendChatMessage(win.udpPlayers[i], "<span color=\"yellow\">[PM] </span>" + txt, author, ChatLocal); sendChatMessage(player, "<span color=\"yellow\">[PM to " + win.udpPlayers[i]->pony.name + "] </span>" + txt, author, ChatLocal); } } } } else if (txt.startsWith(":names")) { QString namesmsg = "<span color=\"yellow\">Players currently in game:</span>"; for (int i=0; i<win.udpPlayers.size(); i++) if (win.udpPlayers[i]->inGame>=2) namesmsg += "<br />#b" + win.udpPlayers[i]->pony.name + "#b<br /><span color=\"yellow\"> - in " + win.udpPlayers[i]->pony.sceneName + "</span>"; sendChatMessage(player, namesmsg, "[Server]", ChatLocal); } else if (txt.startsWith(":tp")) { if (txt.count(" ") < 1) { QString msgtosend = ":tp<br /><span color=\"yellow\">Usage:</span><br /><em>:tp location</em><br /><span color=\"yellow\">Available locations:</span><em>"; for (int i=0; i<win.scenes.size(); i++) msgtosend += "<br />" + win.scenes[i].name; sendChatMessage(player, msgtosend + "</em>", author, ChatLocal); } else sendLoadSceneRPC(player, txt.remove(0, 4)); } else if (txt == ":me") { sendChatMessage(player, ":me<br /><span color=\"yellow\">Usage:</span><br /><em>:me action</em>", author, ChatLocal); } else // Broadcast the message { int rollnum = -1; QString rollstr; bool actmsg = false; if (txt == ":roll") { if (player->chatRollCooldownEnd < QDateTime::currentDateTime()) { rollnum = qrand() % 100; rollstr.sprintf("<span color=\"yellow\">#b%s#b rolls %02d</span>", author.toLocal8Bit().data(), rollnum); player->chatRollCooldownEnd = QDateTime::currentDateTime().addSecs(10); } } if (txt.startsWith(":me ")) { actmsg = true; txt.remove(0, 3); txt = "<em>#b* " + author + "#b" + txt + "</em>"; } if ((quint8)msg[6] == 8) // Local chat only { Scene* scene = findScene(player->pony.sceneName); if (scene->name.isEmpty()) win.logMessage("UDP: Can't find the scene for chat message, aborting"); else { for (int i=0; i<scene->players.size(); i++) { if (scene->players[i]->inGame>=2) { if (rollnum > -1) sendChatMessage(scene->players[i], rollstr, "[Server]", ChatLocal); else if (actmsg) sendChatMessage(scene->players[i], txt, "", ChatLocal); else if (txt.startsWith(">")) sendChatMessage(scene->players[i], "<span color=\"green\">" + txt + "</span>", author, ChatLocal); else sendChatMessage(scene->players[i], txt, author, ChatLocal); } } } } else // Send globally { for (int i=0; i<win.udpPlayers.size(); i++) { if (win.udpPlayers[i]->inGame>=2) { if (rollnum > -1) sendChatMessage(win.udpPlayers[i], rollstr, "[Server]", ChatGeneral); else if (actmsg) sendChatMessage(win.udpPlayers[i], txt, "", ChatGeneral); else if (txt.startsWith(">")) sendChatMessage(win.udpPlayers[i], "<span color=\"green\">" + txt + "</span>", author, ChatGeneral); else sendChatMessage(win.udpPlayers[i], txt, author, ChatGeneral); } } } } }
void receiveChatMessage(QByteArray msg, Player* player) { QString txt = dataToString(msg.mid(7)); QString author = player->pony.name; //logMessage("Chat "+author+":"+txt); if (txt.startsWith("/stuck") || txt.startsWith("unstuck me")) { sendLoadSceneRPC(player, player->pony.sceneName); } else if (txt == ":anhero") { QTimer *anheroTimer = new QTimer(); anheroTimer->setSingleShot(true); QString deadPlayerName = player->name; QObject::connect(anheroTimer, &QTimer::timeout, [=]() { // Find player again instead of reusing pointer, in case they disconnect Player* deadPlayer = Player::findPlayer(Player::udpPlayers, deadPlayerName); if (deadPlayer->connected && deadPlayer->pony.dead) { sendSetStatRPC(deadPlayer, 1, deadPlayer->pony.health); Scene* scene = findScene(deadPlayer->pony.sceneName); for (Player* other : scene->players) sendNetviewInstantiate(&deadPlayer->pony, other); deadPlayer->pony.dead = false; } delete anheroTimer; // Don't delete deadPlayer here. That kills the player's session } ); if (!player->pony.dead) { player->pony.dead = true; sendSetStatRPC(player, 1, 0); anheroTimer->start(5000); Scene* scene = findScene(player->pony.sceneName); for (Player* other : scene->players) sendNetviewRemove(other, player->pony.netviewId, NetviewRemoveReasonKill); } } else if (txt == ":commands") { sendChatMessage(player, "<span color=\"yellow\">List of Commands:</span><br /><em>:roll</em><br /><span color=\"yellow\">Rolls a random number between 00 and 99</span><br /><em>:msg player message</em><br /><span color=\"yellow\">Sends a private message to a player</span><br /><em>:names</em><br /><span color=\"yellow\">Lists all players on the server</span><br /><em>:me action</em><br /><span color=\"yellow\">States your current action</span><br /><em>:tp location</em><br /><span color=\"yellow\">Teleports your pony to the specified region</span>", "[Server]", ChatLocal); } else if (txt.startsWith(":msg")) { if(txt.count(" ") < 2) sendChatMessage(player, ":msg<br /><span color=\"yellow\">Usage:</span><br /><em>:msg player message</em><br /><span color=\"yellow\">Player names are case-insensitive, ignore spaces and you do not need to type out their full name.</span>", author, ChatLocal); else { for (int i=0; i<Player::udpPlayers.size(); i++) { if (Player::udpPlayers[i]->inGame>=2 && Player::udpPlayers[i]->pony.name.toLower().remove(" ") .startsWith(txt.toLower().section(" ", 1, 1))) { txt = txt.remove(0, txt.indexOf(" ", 5) + 1); sendChatMessage(Player::udpPlayers[i], "<span color=\"yellow\">[PM] </span>" + txt, author, ChatLocal); sendChatMessage(player, "<span color=\"yellow\">[PM to " + Player::udpPlayers[i]->pony.name + "] </span>" + txt, author, ChatLocal); } } } } else if (txt.startsWith(":names")) { QString namesmsg = "<span color=\"yellow\">Players currently in game:</span>"; for (int i=0; i<Player::udpPlayers.size(); i++) if (Player::udpPlayers[i]->inGame>=2) namesmsg += "<br />#b" + Player::udpPlayers[i]->pony.name + "#b<br /><span color=\"yellow\"> - in " + Player::udpPlayers[i]->pony.sceneName + "</span>"; sendChatMessage(player, namesmsg, "[Server]", ChatLocal); } else if (txt.startsWith(":tp")) { if (txt.count(" ") < 1) { QString msgtosend = ":tp<br /><span color=\"yellow\">Usage:</span><br /><em>:tp location</em><br /><span color=\"yellow\">Available locations:</span><em>"; for (int i=0; i<Scene::scenes.size(); i++) msgtosend += "<br />" + Scene::scenes[i].name; sendChatMessage(player, msgtosend + "</em>", author, ChatLocal); } else sendLoadSceneRPC(player, txt.remove(0, 4)); } else if (txt == ":me") { sendChatMessage(player, ":me<br /><span color=\"yellow\">Usage:</span><br /><em>:me action</em>", author, ChatLocal); } else // Broadcast the message { int rollnum = -1; QString rollstr; bool actmsg = false; if (txt == ":roll") { if (player->chatRollCooldownEnd < QDateTime::currentDateTime()) { rollnum = qrand() % 100; rollstr.sprintf("<span color=\"yellow\">#b%s#b rolls %02d</span>", author.toLocal8Bit().data(), rollnum); player->chatRollCooldownEnd = QDateTime::currentDateTime().addSecs(10); } } if (txt.startsWith(":me ")) { actmsg = true; txt.remove(0, 3); txt = "<em>#b* " + author + "#b" + txt + "</em>"; } if ((quint8)msg[6] == 8) // Local chat only { Scene* scene = findScene(player->pony.sceneName); if (scene->name.isEmpty()) logMessage(QObject::tr("UDP: Can't find the scene for chat message, aborting")); else { for (int i=0; i<scene->players.size(); i++) { if (scene->players[i]->inGame>=2) { if (rollnum > -1) sendChatMessage(scene->players[i], rollstr, "[Server]", ChatLocal); else if (actmsg) sendChatMessage(scene->players[i], txt, "", ChatLocal); else if (txt.startsWith(">")) sendChatMessage(scene->players[i], "<span color=\"green\">" + txt + "</span>", author, ChatLocal); else sendChatMessage(scene->players[i], txt, author, ChatLocal); } } } } else // Send globally { for (int i=0; i<Player::udpPlayers.size(); i++) { if (Player::udpPlayers[i]->inGame>=2) { if (rollnum > -1) sendChatMessage(Player::udpPlayers[i], rollstr, "[Server]", ChatGeneral); else if (actmsg) sendChatMessage(Player::udpPlayers[i], txt, "", ChatGeneral); else if (txt.startsWith(">")) sendChatMessage(Player::udpPlayers[i], "<span color=\"green\">" + txt + "</span>", author, ChatGeneral); else sendChatMessage(Player::udpPlayers[i], txt, author, ChatGeneral); } } } } }