Appendix¶
Cacher¶
-
class
circleguard.cacher.Cacher(cache, path)[source]¶ Handles compressing and caching replay data to a database.
Parameters: - cache (bool) – Whether or not replays should be cached.
- path (str or
os.PathLike) – The absolute path to the database. If the path does not exist, a fresh database will be created there.
Notes
Each Cacher instance maintains its own database connection.
-
cache(lzma_bytes, replay_info)[source]¶ Caches a replay in the form of a (compressed) lzma stream to the database, linking it to the replay info.
Parameters: - map_id (str) – The map id to insert into the db.
- lzma_bytes (str) – The lzma stream to compress and insert into the db.
- replay_info (
ReplayInfo) – The ReplayInfo object representing this replay.
Notes
If an entry with the given replay info already exists, it is overwritten by the passed lzma.
The lzma string is compressed with wtc compression. See
_compress()andwtc.compress()for more.A call to this method has no effect if the Cacher’s
should_cacheisFalse.
-
revalidate(loader, replay_info)[source]¶ Checks entries in
replay_infoagainst their entries in the database (if any) to look for score id mismatches, indicating an outdated replay. If there are mismatches, the replay is redownloaded and cached from the replay info.Parameters: - loader (
Loader) – The Loader from the circleguard instance to redownload replays with if they are outdated. - replay_info (list[
ReplayInfo]) – A list of ReplayInfo objects containing the up-to-date information of user’s replays.
Raises: CircleguardException– Raised when the redownloaded replay id is lower than the cached replay id. This should never happen and is indicative of either a fault on our end or the api’s end.Also raised if the replay data is not available from the api when redownloaded.
Notes
If the replay is found to be outdated, it will be overwritten by the newer replay in the database.
- loader (
Circleguard¶
-
class
circleguard.circleguard.Circleguard(key, db_path=None, slider_dir=None, loader=None, cache=True)[source]¶ Circleguard investigates replays for cheats.
Parameters: - key (str) – A valid api key. Can be retrieved from https://osu.ppy.sh/p/api/.
- db_path (str or
os.PathLike) – The path to the database file to read and write cached replays. If the path does not exist, a fresh database will be created there. If None, no replays will be cached or loaded from cache. - slider_dir (str or
os.PathLike) – The path to the directory used byslider.library.Libraryto store beatmaps. If None, a temporary directory will be created forslider.library.Libraryand subsequently destroyed when thisCircleguardobject is garbage collected. - loader (
Loader) – This loader will be used instead of the base loader if passed. This must be the class itself, not an instantiation of it. It will be with two args - a key and a cacher.
-
run(loadables, detect, loadables2=None, max_angle=10, min_distance=8) → Iterable[circleguard.result.Result][source]¶ Investigates loadables for cheats.
Parameters: - loadables (list[
Loadable]) – The loadables to investigate. - detect (
Detect) – What cheats to investigate for. - loadables2 (list[
Loadable]) – ForSTEAL, compare each loadable inloadablesagainst each loadable inloadables2for replay stealing, instead of to other loadables inloadables. - max_angle (float) – For
Detect.CORRECTION, consider only points (a,b,c) where∠abc < max_angle. - min_distance (float) – For
Detect.CORRECTION, consider only points (a,b,c) where|ab| > min_distanceand|bc| > min_distance.
Yields: Result– A result representing an investigation of one or more of the replays inloadables, depending on thedetectpassed.Notes
Results are yielded one at a time, as circleguard finishes investigating them. This means that you can process results fromrun()without waiting for all of the investigations to finish.- loadables (list[
-
steal_check(loadables, loadables2=None, method=<Detect.STEAL_SIM: 1>) → Iterable[circleguard.result.StealResult][source]¶ Investigates loadables for replay stealing.
Parameters: - loadables (list[
Loadable]) – The loadables to investigate. - loadables2 (list[
Loadable]) – If passed, compare each loadable inloadablesagainst each loadable inloadables2for replay stealing, instead of to other loadables inloadables. - method (:class`~.Detect`) – What method to use to investigate the loadables for replay stealing.
This should be one of
Detect.STEAL_SIMorDetect.STEAL_CORR, or both (or’d together).
Yields: StealResult– A result representing a replay stealing investigtion into a pair of loadables fromloadablesand/orloadables2.- loadables (list[
-
relax_check(loadables) → Iterable[circleguard.result.RelaxResult][source]¶ Investigates loadables for relax.
Parameters: loadables (list[ Loadable]) – The loadables to investigate.Yields: RelaxResult– A result representing a relax investigation into a loadable fromloadables.
-
correction_check(loadables, max_angle=10, min_distance=8) → Iterable[circleguard.result.CorrectionResult][source]¶ Investigates loadables for aim correction.
Parameters: loadables (list[ Loadable]) – The loadables to investigate.Yields: CorrectionResult– A result representing an aim correction investigation into a loadable fromloadables.
-
load(loadable)[source]¶ Loads a loadable.
Parameters: loadable ( Loadable) – The loadable to load.Notes
This is identical to calling
loadable.load(cg.loader).
-
load_info(loadable_container)[source]¶ Loads a loadable container.
Parameters: loadable ( LoadableContainer) – The loadable container to load.Notes
This is identical to calling
loadable_container.load_info(cg.loader).
-
circleguard.circleguard.set_options(loglevel=None)[source]¶ Set global options for circlecore.
Parameters: logevel (int) – What level to log at. Circlecore follows standard python logging levels, with an added level of TRACE with a value of 5 (lower than debug, which is 10). The value passed to loglevel is passed directly to the setLevel function of the circleguard root logger. WARNING by default. For more information on log levels, see the standard python logging lib.
Comparer¶
-
class
circleguard.comparer.Comparer(replays1, replays2, detect)[source]¶ Manages comparing
Replays for replay stealing.Parameters: Notes
If
replays2is passed, each replay inreplays1is compared against each replay inreplays2. Otherwise, each replay inreplays1is compared against each other replay inreplays1(len(replays1) choose 2comparisons).The order of
replays1andreplays2has no effect; comparing 1 to 2 is the same as comparing 2 to 1.See also
Investigator, for investigating single replays.-
compare()[source]¶ If
replays2is notNone, compares all replays in replays1 against all replays in replays2. Otherwise, compares all replays inreplays1against all other replays inreplays1(len(replays1) choose 2comparisons).Yields: ComparisonResult– Results representing the comparison of two replays.
-
compare_two_replays(replay1, replay2)[source]¶ Compares two
Replays.Parameters: - replay1 (
Replay) – The first replay to compare. - replay2 (
Replay) – The second replay to compare.
Returns: The result of comparing
replay1toreplay2.Return type: - replay1 (
-
static
compute_similarity(xy1, xy2)[source]¶ Calculates the average distance between two sets of cursor position data.
Parameters: - replay1 (ndarray) – The first xy data to compare.
- replay2 (ndarray) – The second xy data to compare.
Returns: The mean distance between the two datasets.
Return type:
-
static
interpolate(t1, t2, xy1, xy2)[source]¶ Interpolates the xy data of the shorter replay to the longer replay.
Returns: The interpolated replay data of the first and second replay respectively. Return type: (ndarray, ndarray) Notes
The length of the two returned arrays will be equal. This is a (desired) side effect of interpolating.
-
Enums¶
-
class
circleguard.enums.Error[source]¶ An enumeration.
-
NO_REPLAY= ['Replay not available.', <class 'circleguard.exceptions.ReplayUnavailableException'>, 'Could not find any replay data. Skipping']¶
-
RATELIMITED= ["Requesting too fast! Slow your operation, cap'n!", <class 'circleguard.exceptions.RatelimitException'>, 'We were ratelimited. Waiting it out']¶
-
RETRIEVAL_FAILED= ['Replay retrieval failed.', <class 'circleguard.exceptions.ReplayUnavailableException'>, 'Replay retrieval failed. Skipping']¶
-
INVALID_KEY= ['Please provide a valid API key.', <class 'circleguard.exceptions.InvalidKeyException'>, 'Please provide a valid api key']¶
-
INVALID_JSON= ['The api broke.', <class 'circleguard.exceptions.InvalidJSONException'>, 'The api returned an invalid json response, retrying']¶
-
UNKNOWN= ['Unknown error.', <class 'circleguard.exceptions.UnknownAPIException'>, 'Unknown error when requesting a replay. Please report this to the developers at https://github.com/circleguard/circlecore']¶
-
-
class
circleguard.enums.RatelimitWeight[source]¶ How much it ‘costs’ to load a replay from the api.
NONEif the load method of a replay makes no api calls.LIGHTif the load method of a replay makes only light api calls (anything butget_replay).HEAVYif the load method of a replay makes any heavy api calls (get_replay).Notes
This value currently has no effect on the program and is reserved for future functionality.
-
NONE= 'None'¶
-
LIGHT= 'Light'¶
-
HEAVY= 'Heavy'¶
-
-
class
circleguard.enums.Detect[source]¶ A cheat, or set of cheats, to investigate for.
Notes
Also defines thresholds we feel are reasonable to determine a replay as cheated. These values are more conservative - that is, we try to not give false positives. You should decide where you fall on the scale of “few false positives, many false negatives” to “many false positives, few false negatives” for yourself, if necessary.
-
STEAL_SIM= 1¶
-
STEAL_CORR= 8¶
-
RELAX= 2¶
-
CORRECTION= 4¶
-
ALL= 15¶
-
STEAL= 1¶
-
SIM_LIMIT= 17¶
-
CORR_LIMIT= 0¶
-
UR_LIMIT= 50¶
-
Exceptions¶
-
exception
circleguard.exceptions.CircleguardException[source]¶ Base class for exceptions in the circleguard program.
-
exception
circleguard.exceptions.InvalidArgumentsException[source]¶ Indicates an invalid argument was passed to one of the flags.
-
exception
circleguard.exceptions.APIException[source]¶ Indicates an error involving the API, which may or may not be fatal.
UnknownAPIExceptions are considered fatal, InternalAPIExceptions are not.
-
exception
circleguard.exceptions.NoInfoAvailableException[source]¶ Indicates that the API returned no information for the given arguments
-
exception
circleguard.exceptions.UnknownAPIException[source]¶ Indicates some error on the API’s end that we were not prepared to handle.
-
exception
circleguard.exceptions.InternalAPIException[source]¶ Indicates a response from the API that we know how to handle.
-
exception
circleguard.exceptions.InvalidKeyException[source]¶ Indicates that an api key was rejected by the api.
-
exception
circleguard.exceptions.RatelimitException[source]¶ Indicates that our key has been ratelimited and we should retry the request at a later date.
-
exception
circleguard.exceptions.InvalidJSONException[source]¶ Indicates that the api returned an invalid json response, and we should retry the request.
Indicates that we expected a replay from the api but it was not able to deliver it.
Investigator¶
-
class
circleguard.investigator.Investigator(replay, detect, max_angle, min_distance, beatmap=None)[source]¶ Manages the investigation of individual
Replays for cheats.Parameters: - replay (
Replay) – The replay to investigate. - detect (
Detect) – What cheats to investigate the replay for. - beatmap (
slider.beatmap.Beatmap) – The beatmap to calculate ur from, with the replay. Should beNoneifDetect.RELAX in detectisFalse.
See also
Comparer, for comparing multiple replays.-
static
aim_correction(replay, max_angle, min_distance)[source]¶ Calculates the angle between each set of three points (a,b,c) and finds points where this angle is extremely acute and neither
|ab|or|bc|are small.Parameters: Returns: Hits where the angle was less than
max_angleand the distance was more thanmin_distance.Return type: list[
Snap]Notes
This does not detect correction where multiple datapoints are placed at the correction site (which creates a small
min_distance).Another possible method is to look at the ratio between the angle and distance.
See also
aim_correction_sam()for an alternative, unused approach involving velocity and jerk.
-
static
aim_correction_sam(replay_data, num_jerks, min_jerk)[source]¶ Calculates the jerk at each moment in the Replay, counts the number of times it exceeds min_jerk and reports a positive if that number is over num_jerks. Also reports all suspicious jerks and their timestamps.
Warning
Unused function. Kept for historical purposes and ease of viewing in case we want to switch to this track of aim correction in the future, or provide it as an alternative.
- replay (
Loadable¶
-
class
circleguard.loadable.Loadable(cache)[source]¶ Represents one or multiple replays, which have replay data to be loaded from some additional source - the osu! api, local cache, or some other location.
Parameters: cache (bool) – Whether to cache the replay data once loaded. -
load(loader, cache)[source]¶ Loads the information this loadable needs to become fully loaded. Details left to the subclass implementation.
Parameters: - loader (
Loader) – The loader to load this loadable with. Although subclasses may not end up using aLoaderto load themselves (if they don’t load anything from the osu api, for instance), a loader is still passed regardless. - cache (bool) – Whether to cache the replay data once loaded. This argument
comes from a parent—either a
LoadableContainerorCircleguarditself. Should the loadable already have a setcachevalue, that should take precedence over the option passed in this method, but if the loadable has no preference then it should respect the value passed here.
- loader (
-
-
class
circleguard.loadable.LoadableContainer(cache)[source]¶ A loadable which contains other loadables. This means that it has three stages - unloaded, info loaded, and loaded.
When info loaded, the
LoadableContainerhasLoadables but they are unloaded.When loaded, the
LoadableContainerhas loadedLoadables.-
load(loader, cache=None)[source]¶ Loads all
Loadables contained by this loadable container.Parameters: loader ( Loader) – The loader to load theLoadables with.
-
all_replays()[source]¶ Returns all the
Replays in this loadable container.Warning
If you want an accurate list of
Replays in this instance, you must callload()on this instance beforeall_replays(). Otherwise, this instance is not info loaded, and does not have a complete list of replays it represents.
-
-
class
circleguard.loadable.ReplayContainer(cache)[source]¶ A LoadableContainer that only holds Replays and subclasses thereof.
ReplayContainer’s start unloaded and become info loaded when
load_info()is called. They become fully loaded whenload()is called (and if this is called when the ReplayContainer is in the unloaded state,load()will load info first, then load the replays.)In the unloaded state, the container has no actual Replay objects. It may have limited knowledge about their number or type.
In the info loaded state, the container has references to Replay objects, but those Replay objects are unloaded.
In the loaded state, the Replay objects are loaded.
-
class
circleguard.loadable.Check(loadables, cache, loadables2=None)[source]¶ Organizes
Loadables and what to investigate them for.Parameters: - loadables (list[
Loadable]) – The loadables to hold for investigation. - cache (bool) – Whether to cache the loadables once they are loaded. This will be
overriden by a
cacheoption set by aLoadableinloadables. It only affects children loadables when they do not have acacheoption set. - loadables2 (list[
Loadable]) – A second set of loadables to hold. Useful for partitioning loadables for a replay stealing investigations.
-
all_loadables()[source]¶ Returns all the
Loadables contained by this check.Returns: All the loadables in this check. Return type: list[ Loadable]See also
Notes
Loadables are very different fromReplays -len(check.all_loadables())will not return the number of replays in the check, for instance.
-
all_replays()[source]¶ Returns all the
Replays in this check. Contrast withall_loadables(), which returns all theLoadables in this check.Returns: All the replays in this check. Return type: list[ Replay]
- loadables (list[
-
class
circleguard.loadable.Map(map_id, span, mods=None, cache=None)[source]¶ A map’s top plays (leaderboard), as seen on the website.
Parameters: - map_id (int) – The map to represent the top plays for.
- span (str or Span) – A comma separated list of ranges of top plays to retrieve.
span="1-3,6,2-4"-> replays in the range[1,2,3,4,6]. - mods (
ModCombination) – If passed, only represent replays played with this exact mod combination. Due to limitations with the api, fuzzy matching is not implemented. <br> This is applied before span``. That is, ifspan="1-2"andmods=Mod.HD, the top twoHDplays on the map are represented. - cache (bool) – Whether to cache the replays once they are loaded.
-
all_replays()[source]¶ Returns all the
Replays in this loadable container.Warning
If you want an accurate list of
Replays in this instance, you must callload()on this instance beforeall_replays(). Otherwise, this instance is not info loaded, and does not have a complete list of replays it represents.
-
class
circleguard.loadable.User(user_id, span, mods=None, cache=None, available_only=True)[source]¶ A user’s top plays (pp-wise, as seen on the website).
Parameters: - user_id (int) – The user to represent the top plays for.
- span (str or Span) – A comma separated list of ranges of top plays to retrieve.
span="1-3,6,2-4"-> replays in the range[1,2,3,4,6]. - mods (
ModCombination) – If passed, only represent replays played with this exact mod combination. Due to limitations with the api, fuzzy matching is not implemented. <br> This is applied beforespan. That is, ifspan="1-2"andmods=Mod.HD, the user’s top twoHDplays are represented. - cache (bool) – Whether to cache the replays once they are loaded.
- available_only (bool) – Whether to represent only replays that have replay data available.
Replays are filtered on this basis after
modsandspanare applied. True by default.
-
all_replays()[source]¶ Returns all the
Replays in this loadable container.Warning
If you want an accurate list of
Replays in this instance, you must callload()on this instance beforeall_replays(). Otherwise, this instance is not info loaded, and does not have a complete list of replays it represents.
-
class
circleguard.loadable.MapUser(map_id, user_id, span={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100}, cache=None, available_only=True)[source]¶ All replays on a map by a user, not just the top replay.
Parameters: - map_id (int) – The map to represent scores by user_id on.
- user_id (int) – The user to represent scores on map_id for.
- span (str or Span) – A comma separated list of ranges of plays to retrieve.
span="1-3,6,2-4"-> replays in the range[1,2,3,4,6]. - cache (bool) – Whether to cache the replays once they are loaded.
- available_only (bool) – Whether to represent only replays that have replay data available.
Replays are filtered on this basis after
spanis applied. True by default.
-
all_replays()[source]¶ Returns all the
Replays in this loadable container.Warning
If you want an accurate list of
Replays in this instance, you must callload()on this instance beforeall_replays(). Otherwise, this instance is not info loaded, and does not have a complete list of replays it represents.
-
class
circleguard.loadable.Replay(weight, cache)[source]¶ A replay played by a player.
Parameters: - weight (
RatelimitWeight) – How much it ‘costs’ to load this replay from the api. - cache (bool) – Whether to cache this replay once it is loaded.
-
timestamp¶ When this replay was played.
Type: datetime.datetime
-
map_id¶ The id of the map the replay was played on, or 0 if unknown or on an unsubmitted map.
Type: int
-
user_id¶ The id of the player who played the replay, or 0 if unknown (if the player is restricted, for instance). Note that if the user id is known, even if the user is restricted, it should still be given instead of 0.
Type: int
-
mods¶ The mods the replay was played with.
Type: ModCombination
-
t¶ A 1d array containing the timestamp for each frame. <br> This is only nonnull after the replay has been loaded.
Type: ndarray[int]
- weight (
-
class
circleguard.loadable.ReplayMap(map_id, user_id, mods=None, cache=None, info=None)[source]¶ A
Replaythat was submitted to online servers.Parameters: - map_id (int) – The id of the map the replay was played on.
- user_id (int) – The id of the player who played the replay.
- mods (ModCombination) – The mods the replay was played with. If
None, the highest scoring replay ofuser_idonmap_idwill be loaded, regardless of mod combination. Otherwise, the replay withmodswill be loaded. - cache (bool) – Whether to cache this replay once it is loaded.
-
class
circleguard.loadable.ReplayPath(path, cache=None)[source]¶ A
Replaysaved locally in a.osrfile.Parameters: - path (str or
os.PathLike) – The path to the replay file. - cache (bool) – Whether to cache this replay once it is loaded. Note that currently
we do not cache
ReplayPathregardless of this parameter.
-
load(loader, cache)[source]¶ Loads the data for this replay from the osr file.
Parameters: - loader (
Loader) – TheLoaderto load this replay with. - cache (bool) – Whether to cache this replay after loading it. This only has an
effect if
self.cacheis unset (None). Note that currently we do not cacheReplayPathregardless of this parameter.
Notes
If
replay.loadedisTrue, this method has no effect.replay.loadedis set toTrueafter this method is finished.- loader (
- path (str or
Loader¶
-
circleguard.loader.request(function)[source]¶ A decorator that handles
requestsand api related exceptions, as well as resetting our ratelimits if appropriate.Parameters: function (callable) – The function to wrap. Notes
Should be wrapped around any function that makes a request; to the api or otherwise.
If it has been more than
Loader.RATELIMIT_RESETsinceLoader.start_time, setsLoader.start_timeto bedatetime.now.
-
circleguard.loader.check_cache(function)[source]¶ A decorator that checks if the passed
ReplayInfohas its replay cached. If so, returns aReplayinstance from the cached data. Otherwise, calls and returns the function as normal.Parameters: function (callable) – The function to wrap. Notes
selfandreplay_infoMUST be the first and second arguments to the function, respectively.Returns: A Replayinstance from the cached data if it was cached, or the return value of the function if not.Return type: Replayor Unknown
-
class
circleguard.loader.Loader(key, cacher=None)[source]¶ Manages interactions with the osu api, using the
ossapiwrapper.Parameters: - key (str) – A valid api key. Can be retrieved from https://osu.ppy.sh/p/api/.
- cacher (
Cacher) – ACacherinstance to manage replay loading/caching. If None, replays will not be loaded from the cache or cached to the database.
Notes
If the api ratelimits the key, we wait until our ratelimits are refreshed and retry the request. Because the api does not provide the time until the next refresh (and we do not use exponential backoff or another retry strategy), if the key is ratelimited because of an interaction not managed by this class, the class may wait more time than necessary for the key to refresh.
ReplayInfo¶
-
class
circleguard.replay_info.ReplayInfo(timestamp, map_id, user_id, username, replay_id, mods, replay_available)[source]¶ A container class representing all the information we get about a replay from the api.
Parameters: - timestamp (
datetime.datetime) – When this replay was set. - map_id (int) – The id of the map the replay was played on.
- user_id (int) – The id of the player who played the replay.
- username (str) – The username of the player who played the replay.
- replay_id (int) – The id of the replay.
- mods (
ModCombination) – The mods the replay was played with. - replay_available (bool) – Whether this replay is available from the api or not.
- timestamp (
Result¶
-
class
circleguard.result.Result(type_: circleguard.enums.ResultType)[source]¶ The result of a test for cheats, either on a single replay or a collection of replays.
Parameters: - ischeat (bool) – Whether one or more of the replays involved is cheated or not.
- type (
ResultType) – What type of cheat test we are representing the results for.
-
class
circleguard.result.InvestigationResult(replay: circleguard.loadable.Replay, type_: circleguard.enums.ResultType)[source]¶ The result of a test for cheats on a single replay.
Parameters: replay ( Replay) – The replay investigated.
-
class
circleguard.result.ComparisonResult(replay1: circleguard.loadable.Replay, replay2: circleguard.loadable.Replay, type_: circleguard.enums.ResultType)[source]¶ The result of a test for cheats by comparing two replays.
Parameters:
-
class
circleguard.result.StealResult(replay1: circleguard.loadable.Replay, replay2: circleguard.loadable.Replay)[source]¶ The result of a test for replay stealing between two replays.
Parameters: - replay1 (
Replay) – One of the replays involved. - replay2 (
Replay) – The other replay involved. - earlier_replay (
Replay) – The earlier of the two replays (when the score was made). This is a reference to either replay1 or replay2. - later_replay (
Replay) – The later of the two replays (when the score was made). This is a reference to either replay1 or replay2. - similarity (int) – The similarity of the two replays (the lower, the more similar). Similarity is, roughly speaking, a measure of the average pixel distance between the two replays.
- correlation (float) – The median correlation of the two replays (the closer to 1, the more correlated). A value of 1.0 would be perfectly correlated, and a result of 0 would be uncorrelated.
- replay1 (
-
class
circleguard.result.StealResultSim(replay1: circleguard.loadable.Replay, replay2: circleguard.loadable.Replay, similarity: float)[source]¶ The result of a test for replay stealing between two replays, using the similarity algorithm.
Parameters: - replay1 (
Replay) – One of the replays involved. - replay2 (
Replay) – The other replay involved. - earlier_replay (
Replay) – The earlier of the two replays (when the score was made). This is a reference to either replay1 or replay2. - later_replay (
Replay) – The later of the two replays (when the score was made). This is a reference to either replay1 or replay2. - similarity (int) – The similarity of the two replays (the lower, the more similar). Similarity is, roughly speaking, a measure of the average pixel distance between the two replays.
- replay1 (
-
class
circleguard.result.StealResultCorr(replay1: circleguard.loadable.Replay, replay2: circleguard.loadable.Replay, correlation: float)[source]¶ The result of a test for replay stealing between two replays, using the similarity algorithm.
Parameters: - replay1 (
Replay) – One of the replays involved. - replay2 (
Replay) – The other replay involved. - earlier_replay (
Replay) – The earlier of the two replays (when the score was made). This is a reference to either replay1 or replay2. - later_replay (
Replay) – The later of the two replays (when the score was made). This is a reference to either replay1 or replay2. - similarity (int) – The similarity of the two replays (the lower, the more similar). Similarity is, roughly speaking, a measure of the average pixel distance between the two replays.
- replay1 (
-
class
circleguard.result.RelaxResult(replay: circleguard.loadable.Replay, ur: float)[source]¶ The result of a test for relax cheats.
Parameters: - replay (
Replay) – The replay investigated. - ur (float) – The (unconverted) unstable rate of the replay. More information on UR available at https://osu.ppy.sh/help/wiki/Accuracy#accuracy
- replay (
Span¶
Utils¶
-
class
circleguard.utils.ColoredFormatter(patern)[source]¶ A subclass of
logging.Formatterthat uses ANSI escape codes to color different parts of thelogging.LogRecordwhen printed to the console.Notes
Adapted from https://stackoverflow.com/a/46482050.
-
format(record)[source]¶ Format the specified record as text.
The record’s attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message.
-
-
circleguard.utils.convert_ur(ur, mods, *, to)[source]¶ Converts an unstable rate to a converted unstable rate, depending on the mods the replay was played with.
Parameters: - ur (float) – The unconverted ur of the replay.
- mods (Mod) – The mods the replay was played with. Only
Mod.DTandMod.HTwill affect the unstable rate conversion. - to (string) – What to convert the ur to. One of
cv(converted) orucv(unconverted).