Exemplo n.º 1
0
void CDBLoger::writeDBLog(const char *pszPlayerID, const short sType, 
    const char *pszMsg, const size_t iLens)
{
    if (Q_INVALID_SOCK == getSock())
    {
        return;
    }

    int64_t iPlayerID = Q_ToNumber<int64_t>(pszPlayerID);

    size_t iBufferLens = sizeof(iPlayerID) + sizeof(sType) + iLens;
    size_t iHeadLens = Q_INIT_NUMBER;
    const char *pszHead = m_objTcpParser.createHead(iBufferLens, iHeadLens);

    m_objMutex.Lock();
    (void)Q_SockWrite(getSock(), pszHead, iHeadLens);
    (void)Q_SockWrite(getSock(), (const char *)&iPlayerID, sizeof(iPlayerID));
    (void)Q_SockWrite(getSock(), (const char *)&sType, sizeof(sType));
    if (0 != iLens
        && NULL != pszMsg)
    {
        (void)Q_SockWrite(getSock(), pszMsg, iLens);
    }
    m_objMutex.unLock();
}
Exemplo n.º 2
0
bool VNCClient::VNCClose()
{
#ifdef _WIN32
    closesocket(getSock());
#else
    close(getSock());
#endif
    if (framebuffer)
        delete[] framebuffer;
    framebuffer = NULL;
    return true;
}
Exemplo n.º 3
0
bool SSLSocket::waitAccepted(uint64_t millis) {
	if(!ssl) {
		if(!Socket::waitAccepted(millis)) {
			return false;
		}
		ssl.reset(SSL_new(ctx));
		if(!ssl)
			checkSSL(-1);

		if(!verifyData) {
			SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
		} else SSL_set_ex_data(ssl, CryptoManager::idxVerifyData, verifyData.get());

		checkSSL(SSL_set_fd(ssl, static_cast<int>(getSock())));
	}

	if(SSL_is_init_finished(ssl)) {
		return true;
	}

	while(true) {
		int ret = SSL_accept(ssl);
		if(ret == 1) {
			dcdebug("Connected to SSL client using %s\n", SSL_get_cipher(ssl));
			return true;
		}
		if(!waitWant(ret, millis)) {
			return false;
		}
	}
}
Exemplo n.º 4
0
bool SSLSocket::waitAccepted(uint32_t millis) {
    if(!ssl) {
        if(!Socket::waitAccepted(millis)) {
            return false;
        }
        ssl.reset(SSL_new(ctx));
        if(!ssl)
            checkSSL(-1);

        checkSSL(SSL_set_fd(ssl, getSock()));
    }

    if(SSL_is_init_finished(ssl)) {
        return true;
    }

    while(true) {
        int ret = SSL_accept(ssl);
        if(ret == 1) {
            dcdebug("Connected to SSL client using %s\n", SSL_get_cipher(ssl));
            return true;
        }
        if(!waitWant(ret, millis)) {
            return false;
        }
    }
}
Exemplo n.º 5
0
/**
 * Clean up and free the ttcp structure
 */
static void ard_tcp_destroy(struct ttcp* ttcp) {
	err_t err = ERR_OK;
	DUMP_TCP_STATE(ttcp);

	if (getSock(ttcp)==-1)
		WARN("ttcp already deallocated!\n");

	if (ttcp->tpcb) {
		tcp_arg(ttcp->tpcb, NULL);
		tcp_sent(ttcp->tpcb, NULL);
		tcp_recv(ttcp->tpcb, NULL);
		tcp_err(ttcp->tpcb, NULL);
		//TEMPORAQARY
		//err = tcp_close(ttcp->tpcb);
		INFO_TCP("Closing tpcb: state:0x%x err:%d\n", ttcp->tpcb->state, err);
	}

	if (ttcp->lpcb) {
		tcp_arg(ttcp->lpcb, NULL);
		tcp_accept(ttcp->lpcb, NULL);
		err = tcp_close(ttcp->lpcb);
		INFO_TCP("Closing lpcb: state:0x%x err:%d\n", ttcp->lpcb->state, err);
	}

	if (ttcp->upcb) {
		udp_disconnect(ttcp->upcb);
		udp_remove(ttcp->upcb);
	}

	if (ttcp->payload)
		free(ttcp->payload);

	free(ttcp);
}
Exemplo n.º 6
0
	void EpollNetwork::init()
	{
		struct epoll_event m_ev;
		int socket = getSock()->getSock();
		memset(&m_ev, 0x00, sizeof(struct epoll_event));
		m_ev.events = EPOLLIN;
		m_ev.data.ptr = new std::shared_ptr<sock::Sock>(getSockPtr());
		epoll_ctl(m_epoll, EPOLL_CTL_ADD, socket, &m_ev);
	}
Exemplo n.º 7
0
static void cleanSockState_cb(void *ctx) {
	struct ttcp* ttcp = ctx;

	int sock = getSock(ttcp);
	if (sock != -1)
		clearMapSockTcp(sock);
	INFO_TCP("TTCP [%p]: cleanSockState_cb %d\n", ttcp, sock);
	_connected = false;
}
Exemplo n.º 8
0
/**
 * Invoked when transfer is done or aborted (non-zero result).
 */
static void ard_tcp_done(struct ttcp* ttcp, int result) {
//	if (result == 0)
//		ard_tcp_print_stats(ttcp);

	if (ttcp->done_cb)
		ttcp->done_cb(ttcp->opaque, result);

	ard_tcp_destroy(ttcp);
	clearMapSockTcp(getSock(ttcp));
}
Exemplo n.º 9
0
void closeConnections()
{
	int i = 0;
	for (; i<MAX_SOCK_NUM; i++)
	{
		void* p = getTTCP(i);
		if (p)
		{
			ttcp_t* _ttcp = (ttcp_t* )p;

			INFO_TCP("Closing connections tpcb[%p] state:0x%x - lpcb[%p] state: 0x%x\n",
					_ttcp->tpcb, _ttcp->tpcb->state, _ttcp->lpcb, _ttcp->lpcb->state);
			//tcp_close(_ttcp->tpcb);
			ard_tcp_destroy(_ttcp);
	    	clearMapSockTcp(getSock(_ttcp));
		}
	}
}
Exemplo n.º 10
0
void ard_tcp_stop(void* ttcp) {
	struct ttcp* _ttcp = (struct ttcp*) ttcp;
	if (_ttcp == NULL)
	{
		WARN("ttcp = NULL!\n");
		return;
	}
	if (_ttcp->mode == TTCP_MODE_TRANSMIT) {
		INFO_TCP("Destroy TCP connection...state:%d\n", _ttcp->tpcb->state);
		ard_tcp_destroy(_ttcp);
    	clearMapSockTcp(getSock(_ttcp));
    	tcp_poll_retries = 0;
	}else{
		INFO_TCP("Closing connection...state:%d\n", _ttcp->tpcb->state);
		DUMP_TCP_STATE(_ttcp);
		if ((_ttcp)&&(_ttcp->tpcb)&&(_ttcp->tpcb->state!=LAST_ACK)&&(_ttcp->tpcb->state!=CLOSED))
		{
			close_conn(_ttcp);
		}
		pending_accept = false;
	}
}
Exemplo n.º 11
0
/**
 * Kommunikation mit dem Server
 *
 * sock: Socket des Servers
 * version: Version des Clients
 * game_id: Game ID des Spiels
 * pipeRead für die pipe
 */
int performConnection(char* version, char* game_id, SharedMem *shm, int pipeRead) {

	char* line = malloc(sizeof(char) * BUFFR);
	char clientMessage[BUFFR];
	char* errorMessage;
	int sock;
	char pipe_read[PIPE_BUF];

	// Temporärer Speicher für das Auslesen von Variablen aus den Serverantworten
	char* temp1 = malloc(sizeof(char) * 20);
	int temp2;
	int temp3;

	/* Flags zum eindeutigen Kommunikation mit Server */
	// Flag mit Phase, in der wir uns befinden
	int phase = 0;
	// Flag ob Spielfeldshm schon erstellt wurde
	int shmflag = 0;
	Spielfeldshm* spielfeld = malloc(sizeof(Spielfeldshm));
	int quitflag = 0;

	int spielfeldID;
	int shmSizefeld;

	sock = getSock(configstruct);

	while (1) {
		// Empfange Nachricht von Server
		getLine(sock, line);

		/* Routine zum Beenden */
		if (exit_flag == 2) {
			// spielfeld entfernen + line, temp1 freigeben
			shmdt(spielfeld);
			free(line);
			free(temp1);

			return EXIT_FAILURE;
		}
		// Servernachricht verarbeiten
		// Switch zwischen positiver/negativer Server Antwort
		switch (line[0]) {
			// positive Antwort
			case '+':

				if (phase == 0) {

					/* Protokollphase Prolog */
					if (strstr(line, "+ MNM Gameserver") != 0) {

						// sende  Protocol Version
						sprintf(clientMessage, "%s %s\n", "VERSION", version);
						sendMessage(sock, clientMessage);

						// lese Serverversion ein + gebe diese aus
						sscanf(line, "%*s %*s %*s v%s", temp1);
						printf("\nServer Version %s\n", temp1);

					} else if (strstr(line, "+ Client version accepted") != 0) {

						// sende Game ID
						sprintf(clientMessage, "%s %s\n", "ID", game_id);
						sendMessage(sock, clientMessage);

						// gebe Info aus
						printf("Client Version %s akzeptiert\n", version);

					} else if (strstr(line, "+ PLAYING") != 0) {

						// sende Player
						sprintf(clientMessage, "%s\n", "PLAYER");
						sendMessage(sock, clientMessage);

						// lese Gametyp ein + kontrolliere diesen
						sscanf(line, "%*s %*s %s", temp1);
						if (strstr(temp1, "NMMorris") == 0) {
							perror("\nFalscher Spieltyp");
							return EXIT_FAILURE;
						}
						printf("Spieltyp %s akzeptiert\n\n", temp1);

						getLine(sock, line); // nächste Zeile

						// lese Spielname ein + gebe diesen aus + speichern in shm
						sscanf(line, "%*s %[^\n]s", temp1);
						printf("Spielname: %s\n", temp1);
						strncpy(shm->spielname, temp1, sizeof(shm->spielname));

					} else if (strstr(line, "+ YOU") != 0) {

						// lese eigene Spielervariablen ein + gebe diese aus + speichern in shm
						sscanf(line, "%*s %*s %d %[^\n]s", &temp2, temp1);
						printf("Du (%s) bist Spieler #%d\n", temp1, temp2 + 1); // Spielernummer nur für die Ausgabe +1 -> Nummern 1-8
						shm->eigspielernummer = temp2;

						if (shm->eigspielernummer < 0) {

							fprintf(stderr, "\nFehler beim Erfassen der Spielernummer: Spielernummer < 0\n");
							return EXIT_FAILURE;
						}

						shm->spieleratt[shm->eigspielernummer].spielernummer = shm->eigspielernummer;	
						strncpy(shm->spieleratt[shm->eigspielernummer].spielername, temp1, sizeof(shm->spieleratt[shm->eigspielernummer].spielername));	
						shm->spieleratt[shm->eigspielernummer].regflag = 1;

						getLine(sock, line); // nächste Zeile

						// lese Anzahl Spieler aus + speichern in shm
						sscanf(line, "%*s %*s %d", &temp2);
						shm->anzahlspieler = temp2;

						if (shm->anzahlspieler < 1) {

							fprintf(stderr, "\nFehler beim Erfassen der Spieleranzahl: Spieleranzahl < 1\n");
							return EXIT_FAILURE;

						}						
						else if (shm->anzahlspieler > 8) {

							fprintf(stderr, "\nFehler beim Erfassen der Spieleranzahl: Spieleranzahl > 8\n");
							return EXIT_FAILURE;

						}
						getLine(sock, line); // nächste Zeile

						// lese Gegner-Spielervariablen ein + gebe diese aus + speichern in shm
						sscanf(line, "%*s %d", &temp2);
						temp1 = strndup(line + 4, strlen(line) - 6);
						temp3 = atoi(strndup(line + 5 + strlen(temp1), 1));

						if (temp3 == 1)
							printf("Spieler #%d (%s) ist bereit\n\n", temp2 + 1, temp1); // Spielernummer nur für die Ausgabe +1 -> Nummern 1-8
						else
							printf("Spieler #%d (%s) ist noch nicht bereit\n\n", temp2 + 1, temp1); // Spielernummer nur für die Ausgabe +1 -> Nummern 1-8

						shm->spieleratt[temp2].spielernummer = temp2;	
						strncpy(shm->spieleratt[temp2].spielername, temp1, sizeof(shm->spieleratt[temp2].spielername));	
						shm->spieleratt[temp2].regflag = temp3;

					} else if (strstr(line, "+ ENDPLAYERS") != 0) {
						// setze Flag für Spielverlaufsphase
						phase = 1;

					}

				} else if (phase == 1) {

					/* Spielverlaufsphase */
					if (strstr(line, "+ WAIT") != 0) {

						// sende "OKWAIT"
						sprintf(clientMessage, "OKWAIT\n");
						sendMessage(sock, clientMessage);
						printf("Warte auf Gegenspieler...\n");

					} else if (strstr(line, "+ MOVE ") != 0) {

						// lese Zeit für Spielzug
						sscanf(line, "%*s %*s %d", &temp2);
						// temp2: Zeit für Spielzug

					} else if (strstr(line, "+ CAPTURE") != 0) {

						// lese Capturewert
						sscanf(line, "%*s %*s %d", &temp2);

						if (shmflag == 1) {
							// setze capture_flag
							spielfeld->capture_flag = temp2;
						}

					} else if (strstr(line, "+ PIECELIST") != 0) {

						// lese Anzahl Spieler/Steine pro Spieler
						sscanf(line, "%*s %*s %d,%d", &temp2, &temp3);
						// temp2: Anzahl Spieler
						// temp3: Anzahl Steine pro Spieler

						/* Spielfeld SHM */
						if (shmflag == 0) {

							// Spielfeld SHM anlegen
							shmSizefeld = sizeof(spielfeld);
							spielfeldID = initshm(shmSizefeld);

							// Überprüfe spielfeldID
							if (spielfeldID < 1) {
								printf("Kein Spielfeld SHM vorhanden\n");
								return EXIT_FAILURE;
							}

							// Spielfeld SHM binden 
							spielfeld = (Spielfeldshm*) attachshm(spielfeldID);

							// Überprüfe Spielfeld SHM auf Fehler
							if (spielfeld == (void *) -1) {
								printf("Fehler beim Binden des Spielfeld SHM\n");
								return EXIT_FAILURE;
							}

							// Steineverfuegbar Anfangswert zuweisen
							spielfeld->steineverfuegbar = 9;

							shm->spielfeldID = spielfeldID;
							shmflag = 1;
						}
						
						spielfeldleeren(spielfeld);
						spielfeld->anzsteine = temp3;

					} else if (strstr(line, "+ PIECE") != 0) {

						// lese Positionen der Steine
						sscanf(line, "%*s PIECE%d.%d %s", &temp2, &temp3, temp1);
						// temp2: Spielernummer
						// temp3: Steinnummer
						// temp1: Position des Steins
						steinespeichern(temp2, temp1, spielfeld);

					} else if (strstr(line, "+ ENDPIECELIST") != 0) {

						if(quitflag ==0){
							// sende "THINKING"
							sprintf(clientMessage, "THINKING\n");
							sendMessage(sock, clientMessage);
						}
						printspielfeld(spielfeld);

					} else if (strstr(line, "+ OKTHINK") != 0) {

						// Flag zur Überprüfung ob Thinker thinken darf (noch zu implementieren) 
						shm->think_flag = 1;

						// Sende Signal SIGUSR1 an Thinker
						kill(getppid(), SIGUSR1);

						// Warten auf shm->think_flag = 1
						while (shm->think_flag == 1) {}

						if (shm->think_flag == 0){

							if (read(pipeRead, pipe_read, PIPE_BUF) == -1) {
								perror("\nFehler beim Lesen aus der Pipe");
								return EXIT_FAILURE;
							}

							sprintf(clientMessage, "PLAY %s\n", pipe_read);

							// sende Spielzug
							sendMessage(sock, clientMessage);
						}

					} else if (strstr(line, "+ MOVEOK") != 0) {

						// Spielzug akzeptiert
						printf("Spielzug akzeptiert\n\n");

					} else if (strstr(line, "+ GAMEOVER") != 0) {

						sscanf(line, "%*s GAMEOVER%d %s", &temp2, temp1);
						printf("Gameover! Spieler %d (%s) hat gewonnen\n", temp2 + 1,temp1);
						quitflag = 1;
					}
					  else if (strstr(line, "+ QUIT") != 0) {

						printf("Verbindung wird abgebaut\n");
				
						kill(getppid(),SIGUSR2);						
						return EXIT_SUCCESS;
					}
				}

				break;

			// negative Antwort - Error Handling
			case '-':

				// gebe Servernachricht aus
				errorMessage = strndup(line + 2, strlen(line) - 2);

				if (strncmp(line, "- exiting", 9) == 0) {
					fprintf(stderr, "\nGame ID nicht gefunden\n");
				} else if (strstr(line, "No free computer player found for that game - exiting") != 0) {
					fprintf(stderr, "\nKein freier Platz vorhanden\n");
				} else if (strstr(line, "Socket timeout - please be quicker next time") != 0) {
					fprintf(stderr, "\nSocket timeout\n");
				} else if (strstr(line, "Protocol mismatch - you probably didn't want to talk to the fabulous gameserver") != 0) {
					fprintf(stderr, "\nProtocol mismatch\n");
				} else if (strstr(line, "We expected you to THINK!") != 0) {
					fprintf(stderr, "\nZuerst OKTHINK senden, erst dann den Spielzug\n");
				} else if (strstr(line, "Destination is already occupied") != 0) {
					fprintf(stderr, "\nSpielzug ungültig: Das Feld ist schon besetzt\n");
				} else if (strstr(line, "You can't capture yourself") != 0) {
					fprintf(stderr, "\nSpielzug ungültig: Du kannst deinen eigenen Stein nicht entfernen\n");
				} else {
					fprintf(stderr, "\nUnerwarteter Serverfehler: %s\n", errorMessage);
				}
				
				return EXIT_FAILURE;

			// default
			default:

				fprintf(stderr, "\nServernachricht kann nicht verarbeitet werden\n");
				return EXIT_FAILURE;

		}
	}
}
Exemplo n.º 12
0
int Monster::mobileCrt() {
    BaseRoom *newRoom=0;
    AreaRoom *caRoom = getAreaRoomParent();
    int     i=0, num=0, ret=0;
    bool    mem=false;


    if( !flagIsSet(M_MOBILE_MONSTER) ||
        flagIsSet(M_PERMENANT_MONSTER) ||
        flagIsSet(M_PASSIVE_EXIT_GUARD)
    )
        return(0);

    if(nearEnemy())
        return(0);

    for(Exit* exit : getRoomParent()->exits) {
        // count up exits
        if(mobileEnter(exit))
            i += 1;
    }

    if(!i)
        return(0);

    num = mrand(1, i);
    i = 0;

    for(Exit* exit : getRoomParent()->exits) {
        if(mobileEnter(exit))
            i += 1;

        if(i == num) {

            // get us out of this room
            if(!Move::getRoom(this, exit, &newRoom))
                return(0);
            if(newRoom->isAreaRoom()) {
                mem = newRoom->getAsAreaRoom()->getStayInMemory();
                newRoom->getAsAreaRoom()->setStayInMemory(true);
            }

            // make sure there are no problems with the new room
            if(!newRoom)
                return(0);
            if(newRoom->countCrt() >= newRoom->getMaxMobs())
                return(0);

            // no wandering between live/construction areas
            if(newRoom->isConstruction() != getRoomParent()->isConstruction())
                return(0);

            if(exit->flagIsSet(X_CLOSED) && !exit->flagIsSet(X_LOCKED)) {
                broadcast(nullptr, getRoomParent(), "%M just opened the %s.", this, exit->getCName());
                exit->clearFlag(X_CLOSED);
            }

            if(flagIsSet(M_WILL_SNEAK) && flagIsSet(M_HIDDEN))
                setFlag(M_SNEAKING);

            if( flagIsSet(M_SNEAKING) &&
                mrand (1,100) <= (3+dexterity.getCur())*3)
            {
                broadcast(::isStaff, getSock(), getRoomParent(), "*DM* %M just snuck to the %s.", this,exit->getCName());
            } else {
                Creature* lookingFor = nullptr;
                if(flagIsSet(M_CHASING_SOMEONE) && hasEnemy() && ((lookingFor = getTarget(false)) != nullptr) ) {

                    broadcast(nullptr, getRoomParent(), "%M %s to the %s^x, looking for %s.",
                        this, Move::getString(this).c_str(), exit->getCName(), lookingFor->getCName());
                }
                else
                    broadcast(nullptr, getRoomParent(), "%M just %s to the %s^x.",
                        this, Move::getString(this).c_str(), exit->getCName());

                clearFlag(M_SNEAKING);
            }


            // see if we can recycle this room
            deleteFromRoom();
            if(caRoom && newRoom == caRoom && newRoom->isAreaRoom()) {
                newRoom = Move::recycle(newRoom->getAsAreaRoom(), exit);
            }
            addToRoom(newRoom);

            // reset stayInMemory
            if(newRoom->isAreaRoom())
                newRoom->getAsAreaRoom()->setStayInMemory(mem);

            lasttime[LT_MON_WANDER].ltime = time(0);
            lasttime[LT_MON_WANDER].interval = mrand(5,60);

            ret = 1;
            break;
        }
    }

    if(mrand(1,100) > 80)
        clearFlag(M_MOBILE_MONSTER);

    return(ret);
}
Exemplo n.º 13
0
bool Creature::doFlee(bool magicTerror) {
    Monster* mThis = getAsMonster();
    Player* pThis = getAsPlayer();
    BaseRoom* oldRoom = getRoomParent(), *newRoom=0;
    UniqueRoom* uRoom=0;

    Exit*   exit=0;
    unsigned int n=0;

    if(isEffected("fear"))
        magicTerror = true;

    exit = getFleeableExit();
    if(!exit) {
        printColor("You couldn't find any place to run to!\n");
        if(pThis)
            pThis->setFleeing(false);
        return(0);
    }

    newRoom = getFleeableRoom(exit);
    if(!newRoom) {
        printColor("You failed to escape!\n");
        return(0);
    }


    switch(mrand(1,10)) {
    case 1:
        print("You run like a chicken.\n");
        break;
    case 2:
        print("You flee in terror.\n");
        break;
    case 3:
        print("You run screaming in horror.\n");
        break;
    case 4:
        print("You flee aimlessly in any direction you can.\n");
        break;
    case 5:
        print("You run screaming for your mommy.\n");
        break;
    case 6:
        print("You run as your life flashes before your eyes.\n");
        break;
    case 7:
        print("Your heart throbs as you attempt to escape death.\n");
        break;
    case 8:
        print("Colors and sounds mingle as you frantically flee.\n");
        break;
    case 9:
        print("Fear of death grips you as you flee in panic.\n");
        break;
    case 10:
        print("You run like a coward.\n");
        break;
    default:
        print("You run like a chicken.\n");
        break;
    }


    broadcast(getSock(), oldRoom, "%M flees to the %s^x.", this, exit->getCName());
    if(mThis) {
        mThis->diePermCrt();
        if(exit->doEffectDamage(this))
            return(2);
        mThis->deleteFromRoom();
        mThis->addToRoom(newRoom);
    } else if(pThis) {
        pThis->dropWeapons();
        pThis->checkDarkness();
        unhide();

        if(magicTerror)
            printColor("^rYou flee from unnatural fear!\n");

        Move::track(getUniqueRoomParent(), &currentLocation.mapmarker, exit, pThis, false);

        if(pThis->flagIsSet(P_ALIASING)) {
            pThis->getAlias()->deleteFromRoom();
            pThis->getAlias()->addToRoom(newRoom);
        }

        Move::update(pThis);
        pThis->statistics.flee();

        if(cClass == CreatureClass::PALADIN && deity != GRADIUS && !magicTerror && level >= 10) {
            n = level * 8;
            n = MIN<long>(experience, n);
            print("You lose %d experience for your cowardly retreat.\n", n);
            experience -= n;
        }

        if(exit->doEffectDamage(this))
            return(2);
        pThis->deleteFromRoom();
        pThis->addToRoom(newRoom);

        for(Monster* pet : pThis->pets) {
            if(pet && inSameRoom(pThis))
                broadcast(getSock(), oldRoom, "%M flees to the %s^x with its master.", pet, exit->getCName());
        }
    }
    exit->checkReLock(this, false);

    broadcast(getSock(), newRoom, "%M just fled rapidly into the room.", this);

    if(pThis) {

        pThis->doPetFollow();
        uRoom = newRoom->getAsUniqueRoom();
        if(uRoom)
            pThis->checkTraps(uRoom);


        if(Move::usePortal(pThis, oldRoom, exit))
            Move::deletePortal(oldRoom, exit);
    }

    return(1);
}