Code Monkey home page Code Monkey logo

valhalla's Introduction

Alt text

Actions Status

What is this?

This project exists to preserve and archive an early version of the game (v28 of global)

Client modifications

  • 00663007 - change to jmp for multiclient
  • 0041BD17 - fill with nop to remove internet explorer iframe advert after client close
  • 0066520B - push to stack resolution in y
  • 00665211 - push to stack resolution in x
  • 0066519c - mov 0x0 instead of 0x10 for windowed mode

Features

General:

  • Simulated latency with jitter (set in config) to make dev environment simulate a real world connections when within network

Login server:

  • Login user
  • Show EULA on first login
  • Perform gender select on first login
  • Pin
  • Display world ribbons
  • Display world messages
  • Display world status (e.g. overpopulated)
  • World selection
  • Lock character creation on world if full
  • Channel selection
  • Create character
  • Delete character
  • Migrate to channel server
  • Show worlds, channels, world status etc from information sent from world server
  • Prevent players from accessing dead channel
  • Server resets login status upon restart for dangling users

World server:

  • Keep track of player count
  • Send information to login server
  • Send IP, port to channel for change channel requests
  • Forward player connects to channels
  • Forward player leaves game to channels
  • Broadcast buddy events
  • Broadcast party events
  • Broadcast guild events
  • Forward whispers
  • Allow gm command to activate exp/drop changes across all channels
  • Allow gm commands to update information displayed at login

Cashshop server:

  • List items
  • Allow purchases via different currencies

Channel server:

  • GM commands
  • Players can see each other
  • Player can change channel
  • Players can see other movement
  • Player chat
  • player use portal
  • Player allocate skill points
  • Player stats
  • Player use skills
  • Player skill logic (haste etc)
  • Player inventory (needs a re-write)
  • Player use item (scrolls, potions etc)
  • Player drop item(s)
  • Player pets
  • NPC visible
  • NPC movement
  • NPC basic chat
  • NPC shops
  • NPC stylist
  • NPC storage
  • PQ scripts
  • Event scripts
  • Load scripts from folder (incl. hot loading)
  • Map instancing
  • Mob visible
  • Mob movement
  • Mob attack
  • Mob skills that cause stat changes
  • Mob death
  • Mob respawn
  • Mob spawns mob(s) on death
  • Mob drops
  • Mob boss HP bar
  • Minigames
  • Whisphers
  • Find / Map in buddy window
  • Buddy list
  • Buddy chat
  • Party
  • Party chat
  • Guild
  • Guild chat
  • Trade
  • Communication Window
  • Quests
  • Reactors
  • Autonomous GM commands which can be started and stopped at will
  • Server resets login status upon restart for dangling characters

Metrics:

  • Channel population
  • Server thread count (OS and Go)
  • Server memory usage (heap and stack)
  • Monster kill rate
  • Ongoing trades
  • Ongoing minigames
  • Ongoing npc script interactions

See screenshots section for an example Grafana dashboard

TODOs

  • Profile the channel server and do the following:
    • Reduce branches in frequent paths
    • Determine which pieces of data if any provide any benefit in being converted SOAs
  • Implement AES crypt (ontop of the shanda) and determine how to enable it in the client
  • Clean up passing nil to interface type function, should be new(type) as this causes nasty to find bugs as the nil value is not the interface itself but the value it holds
  • Move player save database operations into relevant systems

Acknowledgements

  • Sunnyboy for providing a list of idbs for which this project would not have started
  • The following projects were used to help reverse packet structures that were not clearly shown in the idb
  • NX file format (see acknowledgements at link)

NPC chat display info (use this when scripting NPCs)

NPCs are scripted in javscript powered by goja

Taken from here

  • #b - Blue text.
  • #c[itemid]# - Shows how many [itemid] the player has in their inventory.
  • #d - Purple text.
  • #e - Bold text.
  • #f[imagelocation]# - Shows an image inside the .wz files.
  • #g - Green text.
  • #h # - Shows the name of the player.
  • #i[itemid]# - Shows a picture of the item.
  • #k - Black text.
  • #l - Selection close.
  • #m[mapid]# - Shows the name of the map.
  • #n - Normal text (removes bold).
  • #o[mobid]# - Shows the name of the mob.
  • #p[npcid]# - Shows the name of the NPC.
  • #q[skillid]# - Shows the name of the skill.
  • #r - Red text.
  • #s[skillid]# - Shows the image of the skill.
  • #t[itemid]# - Shows the name of the item.
  • #v[itemid]# - Shows a picture of the item.
  • #x - Returns "0%" (need more information on this).
  • #z[itemid]# - Shows the name of the item.
  • #B[%]# - Shows a 'progress' bar.
  • #F[imagelocation]# - Shows an image inside the .wz files.
  • #L[number]# Selection open.
  • \r\n - Moves down a line.
  • \r - Return Carriage
  • \n - New Line
  • \t - Tab (4 spaces)
  • \b - Backwards

Screenshots

Bosses

Metrics

valhalla's People

Contributors

amityahav avatar dependabot[bot] avatar erwinsexpertise avatar hucaru avatar shanqincheng avatar zees-dev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

valhalla's Issues

Refactor database handling

Currently the database is handled by passing around a DB pointer. This method is not as efficient as it could be, and it would be better to have a database package to handle operations rather than multiple packages performing operations.

All architecture proposals are welcome

Go get error

Issue: Getting an error when running go get

Error log:

build github.com/Hucaru/Valhalla: cannot load hash/maphash: malformed module path "hash/maphash": missing dot in first path element

Go version: go version go1.13.8 darwin/amd64

How to replicate:

  • Run go get in clean repo
  • Or run docker-compose up --build in clean repo

Refactor player inventory

Create an inventory struct and either place in a file such as inventory.go in the player package or create a sub package for handling the inventory

How do I start it?

I get an error when starting it, and which version of the client should I use to connect to it?


$ ./Valhalla.exe -type login -config config_login.toml

2022/12/28 16:28:55 Login Server
panic: open Data.nx: The system cannot find the file specified.

goroutine 1 [running]:
github.com/Hucaru/Valhalla/nx.LoadFile(0x1212973, 0x7)
E:/Github/maplestory/Valhalla/nx/load.go:21 +0x2b4
main.(*loginServer).run(0xc000290000)
E:/Github/maplestory/Valhalla/server_login.go:56 +0xb1
main.main()
E:/Github/maplestory/Valhalla/main.go:25 +0x5f3

Can't process login packet

When selecting character to migrate to world, I get pushed back to login screen. I added a couple lines to watch packets and this is what I got:

login-server_1 | 2019/01/13 02:43:37 New client connection from [Address] MY-IP-HERE:5365 login-server_1 | 2019/01/13 02:43:51 Processed LoginRequest Packet: [Packet] (41) : 01 05 00 61 64 6D 69 6E 09 00 4B 69 6C 6C 65 72 73 31 32 00 0C 29 34 F5 B2 CE E0 06 60 00 00 00 00 6B 58 00 00 00 00 02 00 login-server_1 | 2019/01/13 02:43:51 User 3 has logged in from [Address] MY-IP-HERE:5365 login-server_1 | 2019/01/13 02:43:51 Processed LoginCheckLogin Packet: [Packet] (9) : 08 01 01 03 00 00 00 00 00 login-server_1 | 2019/01/13 02:43:54 Processed LoginWorldSelect Packet: [Packet] (3) : 05 00 00 login-server_1 | 2019/01/13 02:43:55 Processed LoginChannelSelect Packet: [Packet] (3) : 04 00 00 login-server_1 | 2019/01/13 02:43:57 Processed LoginSelect Packet: [Packet] (5) : 0B 07 00 00 00 login-server_1 | 2019/01/13 02:43:57 Error in reading from [Address] MY-IP-HERE , closing the connection EOF

General question about security?

Hi, I have been reading the code for fun and for reference. And I would like to ask few questions to clarify my understand if you would allow me.

I can see that we are creating three types of server: login, world, channel, and each are connected together. How do we prevent users from directly connecting to channel server without going to login/world first? I actually just tried it and it does seem to be able to connect, but I didn't go further to see whether I can actually "abuse" it. If we don't want this to be able to happen, how do we enforce the correct order of connecting, or making sure the user is authenticated when connecting to channel serveer?

On another note, what is the purpose of connecting all three types of servers together. I don't think the connection is actually used in the codebase.

Thanks!

Unable to get running - db out of sync?

Cant seem to get past character selection screen - takes me back to login screen.

It seems like the DB SQL is out of sync from the codebase (channelID does not exist in DB SQL - while code assumes its existence).
Additionally the code references "miniGameWins, miniGameDraw, miniGameLoss" columns of the characters db table - these do not exist either.

  • I have manually applied fixes for these 2 issues (created channelID column and removed miniGame references from code); however still can't select character
    • Theres no errors thrown either

NPC scripting

@ErwinsExpertise I have made progress on a script system for NPCs - the scripts are written in JavaScript. Is the following script clear?:

var state = 0
var styles = [31050, 31040, 31000, 31060, 31090, 31020, 31130, 31120, 31140, 31330, 31010]
var goods = [ [1332020],[1332020, 1],[1332009, 0] ]

function run(npc, player) {
	if (npc.next()) {
		state++
	} else if (npc.back()) {
		state--
	}

	if (state == 2) {
		if (npc.yes()) {
			state = 3
		} else if (npc.no()) {
			state = 4
		}
	} else if (state == 4) {
		if (npc.selection() == 1) {
			state = 0
		} else if (npc.selection() == 2) {
			state = 5
		} else if (npc.selection() == 3) {
			state = 6
		} else if (npc.selection() == 4) {
			state = 7
		} else if (npc.selection() == 5) {
			state = 8
		}
	}

	switch(state) {
	case 0:
		npc.sendBackNext("first", false, true)
		break
	case 1:
		npc.sendBackNext("second", true, false)
		break
	case 2:
		npc.sendYesNo("finished")
		break
	case 3:
		npc.sendOK("selection:" + npc.selection() + ", input number:" + npc.inputNumber() + ", input text: " + npc.inputString())
		npc.terminate()
		break
	case 4:
		npc.sendSelection("Select from one of the following:\r\n#L1#Back to start #l\r\n#L2#Styles#l\r\n#L3#Input number#l#L4#Input text#l\r\n#L5#Shop#l")
		break
	case 5:
		npc.sendStyles("Select from the following", styles)
		state = 3
		break
	case 6:
		npc.sendInputNumber("Input a number:", 100, 0, 100)
		state = 3
		break
	case 7:
		npc.sendInputText("Input text:", "default", 0, 100)
		state = 3
		break
	case 8:
		npc.sendShop(goods)
		break
	default:
		npc.sendOK("state " + state)
		npc.terminate()
	}
}

[BUG] Inventory duplicate on equip

I have noticed when either equipping an item from the inventory will allow it to be duplicated.

Steps to recreate:
Obtain item
Equip to character
Relog

Item will then be present on avatar as well as another in the inventory. I haven't really been able to look into this much but creating an issue to log the bug. I am working on monster status/skills atm so I am not able to address this bug at this time.

Items drop onto correct foothold

Currently items drop at the position the monster dies or player drops from which can lead to items floating. They should instead look for the foothold beneath them (possibly also on) and attach to it.

System Scritps

I am thinking/writing the scripting system responsible for handling system wide events e.g. boats and PQs I have the following example script for boat rides (only the scheduler has been implemented):

//Time Setting is in millisecond
var closeGateTime = 240000; //The time to close the gate
var takeoffTime = 300000; //The time at which takeoff occurs
var landTime = 600000; //The time required to land everyone

var invasionTime = 60000; //The time that spawn balrog from takeoffTime between ellinia and orbis

function run(controller) {
    controller.log("run:start")
    // dock the boats in all instances
    // needs to set a property in the map that is then used by npc script to allow ticket sales
    controller.schedule("closeGate", closeGateTime)
    controller.schedule("takeoff", takeoffTime)
    controller.log("run:end")
}

function closeGate(controller) {
    controller.log("closeGate")
    // needs to set a property in the map that is then used by npc script to not sell tickets
}

function takeoff(controller) {
    controller.log("takeoff:start")
    // move characters from boat waiting maps to boat flying map in all instances

    controller.schedule("invasion", invasionTime)
    controller.schedule("land", landTime)
    controller.log("takeoff:end")
}

function invasion(controller) {
    controller.log("invasion")
    // 40% change to spawn
    // spawn 8150000 at 485, -221
    // spawn 8150000 at -590, -221
    // show boat
    // change map bgm (Bgm04/ArabPirate)
}

function land(controller) {
    controller.log("land:start")
    // move characters from boat to stations in all instances

    run(controller)
    controller.log("land:end")
}

If no objections/suggestions are made I will go ahead and finish the implementation.

The scheduler appears to be working correctly:
image

Boat takeoff and docking working off of schedule:
image

Cannot build

Facing issues when building on the master branch:

go build

causes the following error:
build github.com/Hucaru/Valhalla: cannot load github.com/Hucaru/Valhalla/server/field/droppool: no matching versions for query "latest"

Caused by commit cf9095be4ba9cc2f1d14ff65f6bc04eb81f1ee23 in the server/channel_chat.go file

Building out useable items

Currently I am in the process of building out useable items. Currently there is not really a process in the code that builds out useable items other than what is in the info node. For most useable items the important information is actually in spec which is not iterated over.

I am trying to figure out the best way to structure this. While we could always created a nested struct it does not seem necessary

type Item struct {
         Info Info
         Spec Spec
}

type Info struct {
         // Everything in info
}

type Spec struct {
         // Everything in spec
}

This seems like it would be rather tedious and not have any real advantages. The way I am currently experimenting with is by iterating over a slice of subSearches and creating items to map[int]Item . Once the iteration has finished the structs are merged.

				for j := uint32(0); j < uint32(itemGroupNode.ChildCount); j++ {
					itemNode := nodes[itemGroupNode.ChildID+j]
					name := textLookup[itemNode.NameID]

					var item Item
					itemMap := make(map[int]Item)

					subSearches := []string{"/info", "/spec"}
					for i, subSrch := range subSearches {
						subSearch := search + "/" + groupName + "/" + name + subSrch

						valid := gonx.FindNode(subSearch, nodes, textLookup, func(node *gonx.Node) {
							itemMap[i] = getItem(node, nodes, textLookup)
						})

						if !valid {
							log.Println("Invalid node search:", subSearch)
						}

					}
					item = itemMap[0]

					mergo.Merge(&item, itemMap[1])

					name = strings.TrimSuffix(name, filepath.Ext(name))
					itemID, err := strconv.Atoi(name)

					if err != nil {
						log.Println(err)
						continue
					}

					item.InvTabID = byte(itemID / 1e6)
					items[int32(itemID)] = item
				}

This method is using the following package at the cost of reflection:
https://github.com/imdario/mergo

Any ideas that might be more efficient or should this suffice?

Unable to log on to the game server

I'm using master branch

I just add a user in adminers and login to the login-server

The Data.nx convert by v28's Data.wz (Using Wz2Nx)
And I just put Data.nx to the root folder

  • Logs of login-server
2019/02/22 07:30:21 New client connection from [Address] 172.21.0.1:58328
2019/02/22 07:30:29 User 3 has logged in from [Address] 172.21.0.1:58328
2019/02/22 07:30:32 Error in reading from [Address] 172.21.0.1:58328 , closing the connection EOF
2019/02/22 07:30:53 New client connection from [Address] 172.21.0.1:58332

image

image

Build Instructions for Server

Hello! Could anyone please add detailed instructions on how to set up this server for those who are not very knowledgeable with programming? Offline single-player game testing would be fine. Thank you!

Mob Status

I'm currently working on implementing mob status effects( stun, slow, curse, etc) and I am needing the opcode for server to send. I've been looking through IDB but I am not finding what I need. Do you know what this opcode is by chance, or even which method it might be under in IDB?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.