Merge pull request #451 from TES3MP/0.6.3 while resolving conflicts

# Conflicts:
#	apps/openmw-mp/Networking.cpp
#	apps/openmw-mp/main.cpp
#	apps/openmw-mp/processors/object/ProcessorObjectDelete.hpp
This commit is contained in:
David Cernat 2018-06-21 22:31:10 +03:00
commit 524363702c
8 changed files with 97 additions and 23 deletions

View file

@ -313,7 +313,7 @@ void Networking::newPlayer(RakNet::RakNetGUID guid)
if (pl->guid == guid) return; if (pl->guid == guid) return;
// If an invalid key makes it into the Players map, ignore it // If an invalid key makes it into the Players map, ignore it
else if (pl->guid == RakNet::UNASSIGNED_RAKNET_GUID) return; else if (pl->guid == RakNet::UNASSIGNED_CRABNET_GUID) return;
// If we are iterating over a player who has inputted their name, proceed // If we are iterating over a player who has inputted their name, proceed
else if (pl->getLoadState() == Player::POSTLOADED) else if (pl->getLoadState() == Player::POSTLOADED)

View file

@ -235,9 +235,9 @@ int main(int argc, char *argv[])
switch (peer->Startup((unsigned) players, &sd, 1)) switch (peer->Startup((unsigned) players, &sd, 1))
{ {
case RakNet::RAKNET_STARTED: case RakNet::CRABNET_STARTED:
break; break;
case RakNet::RAKNET_ALREADY_STARTED: case RakNet::CRABNET_ALREADY_STARTED:
Utils::throwError("Already started"); Utils::throwError("Already started");
break; break;
case RakNet::INVALID_SOCKET_DESCRIPTORS: case RakNet::INVALID_SOCKET_DESCRIPTORS:

View file

@ -17,14 +17,10 @@ namespace mwmp
{ {
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Received %s from %s", strPacketID.c_str(), player->npc.mName.c_str()); LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Received %s from %s", strPacketID.c_str(), player->npc.mName.c_str());
packet.Send(true);
auto objCtrl = Networking::get().getState().getObjectCtrl(); auto objCtrl = Networking::get().getState().getObjectCtrl();
auto objects = objCtrl.copyObjects(objectList); auto objects = objCtrl.copyObjects(objectList);
Networking::get().getState().getEventCtrl().Call<CoreEvent::ON_OBJECT_DELETE>(player.get(), objects); Networking::get().getState().getEventCtrl().Call<CoreEvent::ON_OBJECT_DELETE>(player.get(), objects);
objCtrl.sendObjects(player, objects, objectList.cell);
} }
}; };
} }

View file

@ -374,12 +374,15 @@ namespace MWGui
{ {
onTakeAllButtonClicked(mTakeButton); onTakeAllButtonClicked(mTakeButton);
if (mPtr.getClass().isPersistent(mPtr))
MWBase::Environment::get().getWindowManager()->messageBox("#{sDisposeCorpseFail}");
/* /*
Start of tes3mp addition Start of tes3mp change (major)
Send an ID_OBJECT_DELETE packet every time a corpse is disposed of Instead of deleting the corpse on this client, simply send an ID_OBJECT_DELETE
packet to the server as a request for the deletion
*/ */
if (!mPtr.getClass().isPersistent(mPtr)) else
{ {
mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList(); mwmp::ObjectList *objectList = mwmp::Main::get().getNetworking()->getObjectList();
objectList->reset(); objectList->reset();
@ -387,14 +390,9 @@ namespace MWGui
objectList->sendObjectDelete(); objectList->sendObjectDelete();
} }
/* /*
End of tes3mp addition End of tes3mp change (major)
*/ */
if (mPtr.getClass().isPersistent(mPtr))
MWBase::Environment::get().getWindowManager()->messageBox("#{sDisposeCorpseFail}");
else
MWBase::Environment::get().getWorld()->deleteObject(mPtr);
mPtr = MWWorld::Ptr(); mPtr = MWWorld::Ptr();
} }
} }

View file

@ -204,14 +204,14 @@ bool CellController::isLocalActor(MWWorld::Ptr ptr)
std::string actorIndex = generateMapIndex(ptr); std::string actorIndex = generateMapIndex(ptr);
return (localActorsToCells.count(actorIndex) > 0 && isInitializedCell(localActorsToCells.at(actorIndex))); return localActorsToCells.count(actorIndex) > 0;
} }
bool CellController::isLocalActor(int refNumIndex, int mpNum) bool CellController::isLocalActor(int refNumIndex, int mpNum)
{ {
std::string actorIndex = generateMapIndex(refNumIndex, mpNum); std::string actorIndex = generateMapIndex(refNumIndex, mpNum);
return (localActorsToCells.count(actorIndex) > 0 && isInitializedCell(localActorsToCells.at(actorIndex))); return localActorsToCells.count(actorIndex) > 0;
} }
LocalActor *CellController::getLocalActor(MWWorld::Ptr ptr) LocalActor *CellController::getLocalActor(MWWorld::Ptr ptr)
@ -247,14 +247,14 @@ bool CellController::isDedicatedActor(MWWorld::Ptr ptr)
std::string actorIndex = generateMapIndex(ptr); std::string actorIndex = generateMapIndex(ptr);
return (dedicatedActorsToCells.count(actorIndex) > 0 && isInitializedCell(dedicatedActorsToCells.at(actorIndex))); return dedicatedActorsToCells.count(actorIndex) > 0;
} }
bool CellController::isDedicatedActor(int refNumIndex, int mpNum) bool CellController::isDedicatedActor(int refNumIndex, int mpNum)
{ {
std::string actorIndex = generateMapIndex(refNumIndex, mpNum); std::string actorIndex = generateMapIndex(refNumIndex, mpNum);
return (dedicatedActorsToCells.count(actorIndex) > 0 && isInitializedCell(dedicatedActorsToCells.at(actorIndex))); return dedicatedActorsToCells.count(actorIndex) > 0;
} }
DedicatedActor *CellController::getDedicatedActor(MWWorld::Ptr ptr) DedicatedActor *CellController::getDedicatedActor(MWWorld::Ptr ptr)

View file

@ -201,7 +201,7 @@ Networking::Networking(): peer(RakNet::RakPeerInterface::GetInstance()), playerP
RakNet::SocketDescriptor sd; RakNet::SocketDescriptor sd;
sd.port=0; sd.port=0;
auto b = peer->Startup(1, &sd, 1); auto b = peer->Startup(1, &sd, 1);
RakAssert(b==RakNet::RAKNET_STARTED); RakAssert(b==RakNet::CRABNET_STARTED);
playerPacketController.SetStream(0, &bsOut); playerPacketController.SetStream(0, &bsOut);
actorPacketController.SetStream(0, &bsOut); actorPacketController.SetStream(0, &bsOut);
@ -305,6 +305,13 @@ void Networking::connect(const std::string &ip, unsigned short port, std::vector
queue = false; queue = false;
break; break;
} }
case ID_INCOMPATIBLE_PROTOCOL_VERSION:
{
errmsg = "Network protocol mismatch!\nMake sure your client is really on the same version\n"
"as the server you are trying to connect to.";
queue = false;
break;
}
case ID_CONNECTION_REQUEST_ACCEPTED: case ID_CONNECTION_REQUEST_ACCEPTED:
{ {
serverAddr = packet->systemAddress; serverAddr = packet->systemAddress;

View file

@ -5,6 +5,8 @@
Include additional headers for multiplayer purposes Include additional headers for multiplayer purposes
*/ */
#include <components/openmw-mp/Log.hpp>
#include "../mwbase/windowmanager.hpp"
#include "../mwmp/Main.hpp" #include "../mwmp/Main.hpp"
#include "../mwmp/CellController.hpp" #include "../mwmp/CellController.hpp"
/* /*
@ -46,7 +48,7 @@ namespace MWWorld
Update LocalActors before we unload their cells, so packets with their cell changes Update LocalActors before we unload their cells, so packets with their cell changes
can be sent can be sent
*/ */
mwmp::Main::get().getCellController()->updateLocal(false); mwmp::Main::get().getCellController()->updateLocal(true);
/* /*
End of tes3mp addition End of tes3mp addition
*/ */
@ -69,6 +71,25 @@ namespace MWWorld
} }
else else
{ {
/*
Start of tes3mp change (major)
Only allow LocalActors to teleport across cells
*/
if (!mwmp::Main::get().getCellController()->isLocalActor(actor))
{
MWBase::Environment::get().getWindowManager()->messageBox("That NPC can't follow you because their AI is running on another player's client.");
return;
}
else
{
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Teleporting actor %s-%i-%i to new cell", actor.getCellRef().getRefId().c_str(),
actor.getCellRef().getRefNum().mIndex, actor.getCellRef().getMpNum());
}
/*
End of tes3mp change (major)
*/
if (mCellName.empty()) if (mCellName.empty())
{ {
int cellX; int cellX;

View file

@ -0,0 +1,52 @@
#include <components/openmw-mp/NetworkMessages.hpp>
#include "PacketWorldMap.hpp"
using namespace std;
using namespace mwmp;
PacketWorldMap::PacketWorldMap(RakNet::RakPeerInterface *peer) : WorldstatePacket(peer)
{
packetID = ID_WORLD_MAP;
}
void PacketWorldMap::Packet(RakNet::BitStream *bs, bool send)
{
WorldstatePacket::Packet(bs, send);
uint32_t changesCount;
if (send)
changesCount = static_cast<uint32_t>(worldstate->mapChanges.mapTiles.size());
RW(changesCount, send);
if (!send)
{
worldstate->mapChanges.mapTiles.clear();
worldstate->mapChanges.mapTiles.resize(changesCount);
}
for (auto &&mapTile : worldstate->mapChanges.mapTiles)
{
RW(mapTile.x, send);
RW(mapTile.y, send);
uint32_t imageDataCount;
if (send)
imageDataCount = static_cast<uint32_t>(mapTile.imageData.size());
RW(imageDataCount, send);
if (!send)
{
mapTile.imageData.clear();
mapTile.imageData.resize(imageDataCount);
}
for (auto &&imageChar : mapTile.imageData)
{
RW(imageChar, send);
}
}
}