Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Providing current position of cursor while playing & Optimize key status #145

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

StageGuard
Copy link

@StageGuard StageGuard commented Aug 17, 2022

Hi maintainers, this is my first try on golang.
This pull request aims at providing current position of cursor while playing and optimize reading key status.

JSON changes

//GameplayValues inside osu!memory
type GameplayValues struct {
	///...
        // previously keyOverlay, now changed to keyCount
        // because key status is moved to hitEvent
	KeyCount    keyCount    `json:"keyCount"`
        // hitEvent array
	HitEvent    []hitEvent  `json:"hitEvents"`
	//...
}

// this is one hit event frame
type hitEvent struct {
	X         float32 `json:"x"` // current x position
	Y         float32 `json:"y"` // current y position
	TimeStamp int32   `json:"timeStamp"` // current game time stamp
	K1        bool    `json:"k1"` // k1 pressed
	K2        bool    `json:"k2"` // k2 pressed
	M1        bool    `json:"m1"` // m1 pressed
	M2        bool    `json:"m2"` // k2 pressed
}

// keyCount uses previous way to read
type keyCount struct {
	K1 int32 `json:"k1"`
	K2 int32 `json:"k2"`
	M1 int32 `json:"m1"`
	M2 int32 `json:"m2"`
}

The hitEvent loads hit event frames from last UpdateTime to current time, about 7 to 15 frames.
X and Y is the position in game hit window, same as the replay frames in .osr files.

How I read

I read these data from game frame memory. This area of memory may have different signature pattern, so I doesn't uses pattern defination like sig:"xx xx" or mem:"[xx]" to read.
I just defined the signature in resolveHitEventAddress() function.

When playing, frame count of hit event in memory increased following game time, while watching replay, the frames all loads to memory at the start.
So I maintain var hitEventFrame []hitEvent to tempory store frames. At every UpdateTime, it will decide which slice to return based on the current game time and the previous game time. Code at here.

Optimize key status

When reading this part of memory, I found that the hit event frames in memory also records key status. This block of memory is next to cursor position.
So I removed previous way of reading key status and introduced a new way here btw.

Game Mode compatibility

X and Y position works in all modes.

  • In std: as mentioned above.
  • In taiko: if X equals to 0, means pressed left side key, 320 means none keys pressed, 640 means pressed right side key.
  • In ctb: X is the position of catcher, ranging from 0 to 512.
  • In mania: X is bit flags of every track, like 0101 or 1111 in 4k.

Also works either single and multiplayer mode.

More functions

  • We can get play mode while playing(wathing replay or playing?) by detecting size changes of hitEventFrame just like this if-else branch, so maybe we can add PlayMode field to GameplayValues to show if player watching replay or playing.
  • We can also define a key counter to record pressed counts by key status, So we need not to rewrite key overlay anymore.

@StageGuard
Copy link
Author

Based on my fork of this project, I've made two counters: https://github.com/StageGuard/gosumemory-pp-curve-overlay

@l3lackShark
Copy link
Owner

Thank You for contributing! I will push some refactor commits soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants