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

HUSS #3302

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

HUSS #3302

wants to merge 3 commits into from

Conversation

Samuel23
Copy link
Contributor

Pull Request Prelude

Changes Proposed

Design

Implementation of the Hercules Ultimate Storage System
Storages can now be created through a configuration file that describes their attributes.
Example storage configuration:

{
        Id: (int)                              (required|unique) Unique Identifier
        Name: (string)                         (required) Name of the storage sent to the client.
        Capacity: (int)                        (required) Maximum capacity of the storage.
}

Additional storages are handled with dynamic arrays that will save a tonne of memory when created, as opposed to a design in which they were implemented using fixed length arrays. In simple terms, a storage of 600 items would approximately cost the same amount of memory as 600 storages with 1 item each.
They are saved in the same storage database (SQL) as the original separating them by a storage identifier.
An infinite number of storages can be created, there are no limits.
The current design implementation only allow saving/loading of approximately 1600 items per storage due to packet size limits.

PS. Make sure you apply SQL upgrades for this patch!

Access Modes

Storage access modes can be set through the openstorage builtin command.

	STORAGE_ACCESS_VIEW     // View storage only
	STORAGE_ACCESS_GET      // Allow getting items from storage.
	STORAGE_ACCESS_PUT      // Allow putting items to storage.
	STORAGE_ACCESS_ALL      // Allow all actions.

Default storage mode : STORAGE_ACCESS_ALL

Script Commands

Changed: openstorage(<storage_id>{, <storage_mode>})

Credits still to: @sagunkho and @dastgirp
Just updated and tested with latest repository version
Issues addressed:

[x] #1763
[x] #2724

@guilherme-gm guilherme-gm self-requested a review June 28, 2024 02:55
Copy link
Member

@guilherme-gm guilherme-gm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, thank you for your PR!

I did an initial review that hopefully covers most of the changes. But I did not test it.

Now to some things not mentioned in the review messages (or only briefly mentioned)

Concern regarding storage sizes

I have some concern regarding misconfiguration of storages, since as far as I can tell:

  1. The inter-server packet does not support splitting, so it is limited to a 65k bytes packet. If a single storage has more items than it fits this space, it would cause issues
  2. The client packet does not support splitting too, so the same applies.

I remember in current code we have an assertion to prevent it from overflowing, but with this new code I don't think we have this check (at least I could not find it). I believe we should have some sort of safe guarding to prevent item losses/misconfiguration.

I guess the easiest solution here would be to calculate how many items are supported in the running server (probably the smallest number between inter-server and client) and limit storage config to now go over this value. If in the future one of those grow and the current user config no longer supports it, they would be informed and could plan the upgrade for their server.

Regarding commits

It would be nice if this was split into commits so that if in the future we'll need to debug an issue near the lines of code edited here, we'll be able to figure out if a change was intentional or accidental by reading the commit messages.

I can help splitting it if you can't or don't know how.

My suggestion regarding how to split it is:

  1. Convert a single storage from array to vector
  2. Add storage config loading (but not being used yet)
  3. Add multiple storages (at this moment, let openstorage command just open the storage id 1)
  4. Update openstorage with storage id param + NPCs (No access code for now)
  5. Add access type parameter
  6. Update other atcommands (maybe with 1 commit for each changed command)

(If some changes doesn't fall into any of those, make a separate commit)


Again, thank you for your contribution and feel free to ask if needed :)

@@ -235,7 +235,6 @@ groups: (
jail: true
jailfor: true
mute: true
storagelist: true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the removal of storagelist permission and @storagelist atcommand intentional? I did not see this mention on the PR nor commit message about why this atcommand is being removed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, this PR is just #2724 rebased, so it has the same caveats as the original. Which includes no default storage and not having implemented some conveniences like @storagelist command. Do keep in mind this got the point of "no changes requested by team" before being entirely forgotten by said team and rendered un-mergeable. Most issues you pointed out either weren't considered an issue in the original or are just maintenance upkeep. Large, complex, non-urgent PRs like this one suffer from an unreasonably large maintenance upkeep. Usually something with only two or one or none of these three attributes get in, breaking the PR and thus the high maintenance upkeep. Honorable mention to #466 which is another good example of death by upkeep.

...Although for these design decisions you can ask @dastgirp as they are the original author, I guess? I don't think they'll remember much though, it has been four years already.

(To be more clear and if memory serves as it's been a long time since I looked at the original, @storagelist will not work with this PR short of a total rewrite of the command, so it was decided to do a regression and remove the command, as it's seldom used and out of scope, from the discussions if it should list all storages or take an argument, up to the actual implementation which would add even more stuff to review in an already large PR. There was no objection from the original reviewers).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, this PR is just #2724 rebased, so it has the same caveats as the original. Which includes no default storage and not having implemented some conveniences like @storagelist command. Do keep in mind this got the point of "no changes requested by team" before being entirely forgotten by said team and rendered un-mergeable. Most issues you pointed out either weren't considered an issue in the original or are just maintenance upkeep. Large, complex, non-urgent PRs like this one suffer from an unreasonably large maintenance upkeep. Usually something with only two or one or none of these three attributes get in, breaking the PR and thus the high maintenance upkeep. Honorable mention to #466 which is another good example of death by upkeep.

...Although for these design decisions you can ask @dastgirp as they are the original author, I guess? I don't think they'll remember much though, it has been four years already.

(To be more clear and if memory serves as it's been a long time since I looked at the original, @storagelist will not work with this PR short of a total rewrite of the command, so it was decided to do a regression and remove the command, as it's seldom used and out of scope, from the discussions if it should list all storages or take an argument, up to the actual implementation which would add even more stuff to review in an already large PR. There was no objection from the original reviewers).

Name: "Storage"
Capacity: 600
},
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add an empty line at the end of the file, this makes it friendlier for diffs/version control systems.

}
*******************************************************************************/
{
// DO NOT EDIT THIS ENTRY!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indent issue here


ALTER TABLE `storage` ADD `storage_id` INT UNSIGNED NOT NULL DEFAULT '1' AFTER `account_id`;

INSERT INTO `sql_updates` (`timestamp`) VALUES (1718685120);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add an empty line at the end of the file

struct storage_data {
int uid; ///< Storage Identifier.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indent issue

}
}
else {
clif->message(fd, msg_fd(fd, 68)); // Please specify a storage name (usage: @storage <storage name>).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use MSGTBL_ constants here

Comment on lines +5680 to +5698
if (*message != '\0' && sscanf(message, "%12d", &intval) == 1) {
if (storage->get_settings(intval) == NULL) {
snprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd, 67), storage_name);
clif->message(fd, atcmd_output); // Invalid storage name or ID.
return false;
}
storage_id = intval;
}
else if (*message != '\0' && sscanf(message, "%23s", storage_name) == 1) {
if ((storage_id = storage->get_id_by_name(storage_name)) == -1) {
snprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd, 67), storage_name);
clif->message(fd, atcmd_output); // Invalid storage name or ID.
return false;
}
}
else {
clif->message(fd, msg_fd(fd, 65)); // Please specify a storage name (usage: @storeall <storage name>).
return false;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here for previous review messages:

  • fix style in else if/else
  • use MSGTBL_* constants

Comment on lines +5741 to +5759
if (*message != '\0' && sscanf(message, "%12d", &intval) == 1) {
if (storage->get_settings(intval) == NULL) {
snprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd, 67), storage_name);
clif->message(fd, atcmd_output); // Invalid storage name or ID.
return false;
}
storage_id = intval;
}
else if (*message != '\0' && sscanf(message, "%23s", storage_name) == 1) {
if ((storage_id = storage->get_id_by_name(storage_name)) == -1) {
snprintf(atcmd_output, sizeof(atcmd_output), msg_fd(fd, 67), storage_name);
clif->message(fd, atcmd_output); // Invalid storage name or ID.
return false;
}
}
else {
clif->message(fd, msg_fd(fd, 66)); // Please specify a storage name (usage: @clearstorage <skill name>).
return false;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here for previous review messages:

  • fix style in else if/else
  • use MSGTBL_* constants

Comment on lines -8768 to -8772
if( strcmpi(info->command, "storagelist") == 0 ) {
location = "storage";
items = VECTOR_DATA(sd->storage.item);
size = VECTOR_LENGTH(sd->storage.item);
} else if( strcmpi(info->command, "cartlist") == 0 ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is the command being removed?

Comment on lines -434 to -435
ShowError("intif_parse_account_storage_save_ack: Storage has not been saved! (AID: %d)\n", account_id);
sd->storage.save = true; // Flag it as unsaved, to re-attempt later
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intended that a failure is no longer retried? Per my understanding, a failure would be eventually retried in the original code, but now if it fails, it will never be saved (potentially leading to a exploit/item loss)

@guilherme-gm guilherme-gm changed the base branch from stable to master June 29, 2024 22:48
@MishimaHaruna MishimaHaruna added this to the Release v2024.07 milestone Jun 30, 2024
@vBrenth
Copy link

vBrenth commented Sep 4, 2024

Still waiting for this to get implemented officially.

@SombraRO
Copy link

SombraRO commented Nov 1, 2024

In 5 years maybe this will be implemented

@vBrenth
Copy link

vBrenth commented Nov 1, 2024

In 5 years maybe this will be implemented

Hahahahahahaha, Well i have this on my emulator already. Its just i want to make this one officially implemented. Im using it for like 2 years now.

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.

6 participants