// Write data to socket stream
func (cw *ConnectionWrapper) SendPoller() {
	for {
		// Read messages from transmit channel
		netmessage := <-cw.txChan

		if netmessage == nil {
			log.Debug("ConnectionWrapper", "SendPoller", "Netmessage == nil, breaking loop")
			break
		}

		// Convert netmessage to packet
		packet := netmessage.WritePacket()
		packet.SetHeader()

		// Create byte buffer
		buffer := packet.GetBuffer()
		data := buffer[0:packet.GetMsgSize()]

		// Send bytes off to the internetz
		websocket.Message.Send(cw.socket, data)
	}
}
Beispiel #2
0
func internalCreatureMove(_creature interfaces.ICreature, _direction uint16) world.ReturnValue {
	ret := world.RET_NOTPOSSIBLE

	if _creature.CanMove() {
		sourcePosition := _creature.GetPosition()
		destinationPosition := _creature.GetPosition()

		switch _direction {
		case interfaces.DIR_NORTH:
			destinationPosition.Y -= 1
		case interfaces.DIR_SOUTH:
			destinationPosition.Y += 1
		case interfaces.DIR_WEST:
			destinationPosition.X -= 1
		case interfaces.DIR_EAST:
			destinationPosition.X += 1
		}

		// Current TilePointLayer
		srcTpl, retValue := world.GetTilePointLayer(sourcePosition.MapId, sourcePosition.X, sourcePosition.Y, sourcePosition.Z)
		if retValue != world.RET_NOERROR {
			log.Debug("Game", "internalCreatureMove", "Source '[%d] %s' not found!", sourcePosition.MapId, sourcePosition.String())
			return retValue
		}

		// Destination TilePointLayer
		dstTpl, retValue := world.GetTilePointLayer(destinationPosition.MapId, destinationPosition.X, destinationPosition.Y, destinationPosition.Z)
		if retValue != world.RET_NOERROR {
			log.Debug("Game", "internalCreatureMove", "Destination '[%d] %s' not found!", destinationPosition.MapId, destinationPosition.String())
			return retValue
		}

		// Move creature to destination tile
		if ret = srcTpl.RemoveCreature(_creature, true); ret == world.RET_NOTPOSSIBLE {
			return ret
		}

		if ret = dstTpl.AddCreature(_creature, true); ret == world.RET_NOTPOSSIBLE {
			srcTpl.AddCreature(_creature, false) // Something went wrong. Put creature back on src TilePoint
			_creature.SetPosition(sourcePosition)
			return ret
		}

		if ret == world.RET_NOERROR {
			_creature.SetPosition(destinationPosition)
			finalDestination := _creature.GetPosition()

			// Get list of creatures who're "new"
			visibleCreatures := world.GetVisibleCreaturesInDirection(finalDestination.MapId, finalDestination.X, finalDestination.Y, finalDestination.Z, _direction)

			for _, value := range visibleCreatures {
				if value != nil {
					_creature.AddVisibleCreature(value)
				}
			}

			// Tell Creature he has moved
			_creature.Walk(sourcePosition, destinationPosition, false, _direction)
		}
	}

	return ret
}
Beispiel #3
0
// Check login credentials
// Returns nothing. If incomming packet is wrong connection is closed, otherwise the login result will be send to the client
func parseFirstMessage(_conn *websocket.Conn, _packet *pnet.Packet) {
	// Read packet header
	header, err := _packet.ReadUint8()
	if err != nil || (err == nil && header != pnet.HEADER_LOGIN) {
		_conn.Close()
		return
	}

	// Parse packet, we can use the same packet for sending the return status
	firstMessage := &netmsg.LoginMessage{}
	if err := firstMessage.ReadPacket(_packet); err != nil {
		_conn.Close()
		return
	}

	// Create wrapper for websocket connection
	connection := NewConnectionWrapper(_conn)

	// TODO: Add pointer to Hood ORM
	player, err := data.PlayerHelper.GetPlayerUsingCredentials(nil, firstMessage.Username, firstMessage.Password)
	if err != nil {
		firstMessage.Status = netmsg.LOGINSTATUS_WRONGACCOUNT
		log.Debug("GameServer", "parseFirstMessage", "Invalid credentials for '%s'. Error: %s", firstMessage.Username, err.Error())
	} else {
		var playerLoaded bool = false
		// Check if player is already logged in
		if uid, found := gameserver.connectedPlayers.Get(player.GetPlayerId()); found {
			if _, f := game.GetPlayerByUID(uid.(uint64)); f {
				playerLoaded = true
			} else {
				// Remove player from connected player list
				gameserver.connectedPlayers.Remove(player.GetPlayerId())
			}
		}

		if playerLoaded {
			firstMessage.Status = netmsg.LOGINSTATUS_ALREADYLOGGEDIN
			log.Debug("GameServer", "parseFirstMessage", "Player '%s' is already logged in", firstMessage.Username)
		} else {
			// Load rest of player data into player object
			if !player.LoadCharacterData() {
				firstMessage.Status = netmsg.LOGINSTATUS_FAILPROFILELOAD
				log.Debug("GameServer", "parseFirstMessage", "Failed to load profile for '%s'", firstMessage.Username)
			} else {
				firstMessage.Status = netmsg.LOGINSTATUS_READY
				log.Debug("GameServer", "parseFirstMessage", "Login OK - Player: %s", player.GetName())

				// Assign connection to player, so Netmessages are handled through player object
				connection.AssignToPlayer(player)
				connection.txChan <- firstMessage

				// Add Player object to game
				game.AddPlayer(player)

				return
			}
		}
	}

	connection.txChan <- firstMessage
	connection.Close()
}