L2JMobius
Public Development => Shares/Contributions => Topic started by: mastermind007 on April 08, 2026, 02:11:17 AM
-
Hello All,
At Mobius request I convert the Ghost Services into a standalone module.
You can access it here https://gitlab.com/Mastermind007/l2jmobius-ghost-services.git (https://gitlab.com/Mastermind007/l2jmobius-ghost-services.git)
The readme file has all the detail but the short version is add the GhostServices folder to your servers "data/scripts/custom".
Go to the config folder and enable the shops, manufacture and wanderers (change from False to True).
Start your server as normal.
Now that this module is not coded in the care it should be easier to test with other chronicles.
--Mastermind007
EDIT: Here is a video showing the mod in use. This is spawning 200 shops between Giran and Dion. The characters you see running around are the Ghost Wanderers that will buy from real player shops only, if the price is right.
https://youtu.be/v-Uf8ErwQz4 (https://youtu.be/v-Uf8ErwQz4)
-
I'm having trouble adding high-value items. I get an error about the format being incorrect. How can I fix this?
-
I'm having trouble adding high-value items. I get an error about the format being incorrect. How can I fix this?
Not sure how you are adding items but I am guessing it is using the shopitems.xml file. Make sure to follow the layout of an existing item in the same category exaactly.
<item id="299" name="Orcish Poleaxe" category="Weapon"><MinCount val="1" /><MaxCount val="1" /><BuyLow val="2800000" /><BuyHigh val="3500000" /><SellLow val="3800000" /><SellHigh val="5000000" /><Level val="1" /></item>
Make sure the category matches exactly as they are used in the code.
Make sure the counts (min/max), as well as the Buy/Sell low and high also have a value. They are quoted in the XML but need to be numbers.
Lastly the Level is a number assigned to the item grade. 1 through 5 equals D through S grade. This is used to limit the type of items available in Dion only. Every item as a grade associated, even craft mats. Dion gets 1 and 2 (D and C grade) only. Giran has no restriction
It you share exactly what you are wanting to add and what you have so far, I am sure we can get it figured out.
EDIT: This will make life a little easier. This link is for a MySQL dump of the current shopitems table used to create the XML items. https://pastebin.com/kQf0PPdr (https://pastebin.com/kQf0PPdr)
Add your new items to the table using your favorite MySQL tool. You can also update prices on existing items to fit your server
When finished the following query will output the items in the correct XML format. If you only want to create one or two just add a where clause to the query so it only outputs those items. All that is left is to paste then in the XML file and reload the server.
SELECT
CONCAT(
'<item id="', id, '" name="', NAME, '" category="', category, '">',
'<MinCount val="', MinCount, '" />',
'<MaxCount val="', MaxCount, '" />',
'<BuyLow val="', BuyLow, '" />',
'<BuyHigh val="', BuyHigh, '" />',
'<SellLow val="', SellLow, '" />',
'<SellHigh val="', SellHigh, '" />',
'<Level val="', LEVEL, '" />',
'</item>'
) AS xml_row
FROM shopitems;
-
Not sure how you are adding items but I am guessing it is using the shopitems.xml file. Make sure to follow the layout of an existing item in the same category exaactly.
<item id="299" name="Orcish Poleaxe" category="Weapon"><MinCount val="1" /><MaxCount val="1" /><BuyLow val="2800000" /><BuyHigh val="3500000" /><SellLow val="3800000" /><SellHigh val="5000000" /><Level val="1" /></item>
Make sure the category matches exactly as they are used in the code.
Make sure the counts (min/max), as well as the Buy/Sell low and high also have a value. They are quoted in the XML but need to be numbers.
Lastly the Level is a number assigned to the item grade. 1 through 5 equals D through S grade. This is used to limit the type of items available in Dion only. Every item as a grade associated, even craft mats. Dion gets 1 and 2 (D and C grade) only. Giran has no restriction
It you share exactly what you are wanting to add and what you have so far, I am sure we can get it figured out.
EDIT: This will make life a little easier. This link is for a MySQL dump of the current shopitems table used to create the XML items. https://pastebin.com/kQf0PPdr (https://pastebin.com/kQf0PPdr)
Add your new items to the table using your favorite MySQL tool. You can also update prices on existing items to fit your server
When finished the following query will output the items in the correct XML format. If you only want to create one or two just add a where clause to the query so it only outputs those items. All that is left is to paste then in the XML file and reload the server.
SELECT
CONCAT(
'<item id="', id, '" name="', NAME, '" category="', category, '">',
'<MinCount val="', MinCount, '" />',
'<MaxCount val="', MaxCount, '" />',
'<BuyLow val="', BuyLow, '" />',
'<BuyHigh val="', BuyHigh, '" />',
'<SellLow val="', SellLow, '" />',
'<SellHigh val="', SellHigh, '" />',
'<Level val="', LEVEL, '" />',
'</item>'
) AS xml_row
FROM shopitems;
this value gives an error:
<BuyLow val="6062212500" /><BuyHigh val="7062212500" /><SellLow val="6062212500" /><SellHigh val="7062212500" />Writes this error:
[main] ERROR org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopItemData - GhostShopItemData: Error loading Shop XML:
java.lang.NumberFormatException: For input string: "6062212500"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:527)
at java.base/java.lang.Integer.parseInt(Integer.java:624)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopItemData.parseItem(GhostShopItemData.java:80)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopItemData.load(GhostShopItemData.java:50)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopItemData.<init>(GhostShopItemData.java:31)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopItemData$SingletonHolder.<clinit>(GhostShopItemData.java:125)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopItemData.getInstance(GhostShopItemData.java:102)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopManager.applyItemsToOfflineShop(GhostShopManager.java:331)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopManager.createOfflineGhostShop(GhostShopManager.java:189)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopManager.createGhostShopRandom(GhostShopManager.java:140)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopManager.startBatchSpawning(GhostShopManager.java:589)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopManager.initStartupSpawns(GhostShopManager.java:570)
at org.l2jmobius.gameserver.GameServer.<init>(GameServer.java:510)
at org.l2jmobius.gameserver.GameServer.main(GameServer.java:601)
-
this value gives an error:
<BuyLow val="6062212500" /><BuyHigh val="7062212500" /><SellLow val="6062212500" /><SellHigh val="7062212500" />Writes this error:
[main] ERROR org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopItemData - GhostShopItemData: Error loading Shop XML:
java.lang.NumberFormatException: For input string: "6062212500"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
at java.base/java.lang.Integer.parseInt(Integer.java:527)
at java.base/java.lang.Integer.parseInt(Integer.java:624)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopItemData.parseItem(GhostShopItemData.java:80)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopItemData.load(GhostShopItemData.java:50)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopItemData.<init>(GhostShopItemData.java:31)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopItemData$SingletonHolder.<clinit>(GhostShopItemData.java:125)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopItemData.getInstance(GhostShopItemData.java:102)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopManager.applyItemsToOfflineShop(GhostShopManager.java:331)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopManager.createOfflineGhostShop(GhostShopManager.java:189)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopManager.createGhostShopRandom(GhostShopManager.java:140)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopManager.startBatchSpawning(GhostShopManager.java:589)
at org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopManager.initStartupSpawns(GhostShopManager.java:570)
at org.l2jmobius.gameserver.GameServer.<init>(GameServer.java:510)
at org.l2jmobius.gameserver.GameServer.main(GameServer.java:601)
That price is way higher than expected. 6 billion adena? Is that correct or a typo?
The cause it the parser uses a standard integer which in java has a max value of 2,147,483,647
To allow for such high values the code would need changed in both GhostShopItem.java and GhostShopItemData.java, changing int to long for the buy and sell low/high. I am not in a position to do that now but maybe tomorrow I can take a look.
-
It's a good contribution; it would be good to adapt them to all projects.
-
That price is way higher than expected. 6 billion adena? Is that correct or a typo?
The cause it the parser uses a standard integer which in java has a max value of 2,147,483,647
To allow for such high values the code would need changed in both GhostShopItem.java and GhostShopItemData.java, changing int to long for the buy and sell low/high. I am not in a position to do that now but maybe tomorrow I can take a look.
Yes, that's exactly the value. I implemented this mod into the Wolf Vagr Chronicles. And that's the price of the items there.
-
That price is way higher than expected. 6 billion adena? Is that correct or a typo?
The cause it the parser uses a standard integer which in java has a max value of 2,147,483,647
To allow for such high values the code would need changed in both GhostShopItem.java and GhostShopItemData.java, changing int to long for the buy and sell low/high. I am not in a position to do that now but maybe tomorrow I can take a look.
and I changed int to long in this file, but nothing changed, the error is still there.
-
and I changed int to long in this file, but nothing changed, the error is still there.
There are multiple places the int needed changed to long.
I made the change and push a commit to the repo mention in my initial post.
Did adding this mod to Wolf Vagr give you any issues, other than the price value?
Was hoping the code for newer chronicles did not change much so it would be usable with them.
-
There are multiple places the int needed changed to long.
I made the change and push a commit to the repo mention in my initial post.
Did adding this mod to Wolf Vagr give you any issues, other than the price value?
Was hoping the code for newer chronicles did not change much so it would be usable with them.
The only problem was the price.
-
There's an issue with replacing merchants and ghost buyers. When it comes time to replace existing merchants and buyers, the system doesn't replace them, but simply adds new ones. What's responsible for removing ghost merchants and buyers from the game and replacing them with new ones?
-
There's an issue with replacing merchants and ghost buyers. When it comes time to replace existing merchants and buyers, the system doesn't replace them, but simply adds new ones. What's responsible for removing ghost merchants and buyers from the game and replacing them with new ones?
Shops:
Towards the end of the "createOfflineGhostShop" there is the line
schedulePurge(ghost.getObjectId(), name, Rnd.get(ROTATION_MIN_HOURS, ROTATION_MAX_HOURS) * ROTATION_MAX_HOURS_MULTIPLIER);
The "schedulePurge" creates that actual timer for the shop to remove the it and start a replacement shop.
You should soo the message in the server log when this fires LOG.info("Rotated out {} (ID: {})", name, objectId);
Buyers:
They follow a similar approach but beings there are far fewer of then that shops they rotate out as a group. The "scheduleNextRotation()" establishes the schedule based on the min/max hours set in the config file. When the event fires all are replaced with new ones.
When this fires you should see a server log message LOG.info("Batch rotated successfully.");
I guess to start are you seeing any of this messages in the log?
-
Shops:
Towards the end of the "createOfflineGhostShop" there is the line
schedulePurge(ghost.getObjectId(), name, Rnd.get(ROTATION_MIN_HOURS, ROTATION_MAX_HOURS) * ROTATION_MAX_HOURS_MULTIPLIER);
The "schedulePurge" creates that actual timer for the shop to remove the it and start a replacement shop.
You should soo the message in the server log when this fires LOG.info("Rotated out {} (ID: {})", name, objectId);
Buyers:
They follow a similar approach but beings there are far fewer of then that shops they rotate out as a group. The "scheduleNextRotation()" establishes the schedule based on the min/max hours set in the config file. When the event fires all are replaced with new ones.
When this fires you should see a server log message LOG.info("Batch rotated successfully.");
I guess to start are you seeing any of this messages in the log?
Yes, the server console says everything went well, but in fact it added new ones and didn't delete the old ones.
-
:07] New maximum connected count of 643!
[L2jMobius ScheduledThread 48] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopGiranManager - Rotated out Ithenlan (ID: 268513085)
[17/04 19:55:09] New maximum connected count of 644!
[L2jMobius ScheduledThread 43] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopRunaManager - Rotated out Елонбане (ID: 268515633)
[L2jMobius ScheduledThread 9] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopGiranManager - Rotated out Faerentide (ID: 268511695)
[17/04 19:55:12] New maximum connected count of 645!
[L2jMobius ScheduledThread 53] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopRunaManager - Rotated out Силиус (ID: 268512434)
[17/04 19:55:14] New maximum connected count of 647!
[L2jMobius ScheduledThread 75] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopGiranManager - Rotated out Zansong (ID: 268515750)
[L2jMobius ScheduledThread 40] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopRunaManager - Rotated out Валбане (ID: 268512855)
[L2jMobius ScheduledThread 49] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopGiranManager - Rotated out Ithius (ID: 268515995)
[17/04 19:55:21] New maximum connected count of 648!
[L2jMobius ScheduledThread 76] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopRunaManager - Rotated out Кинтхас (ID: 268512553)
[L2jMobius ScheduledThread 6] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopRunaManager - Rotated out Оникстхас (ID: 268510859)
[17/04 19:55:24] New maximum connected count of 650!
[L2jMobius ScheduledThread 39] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopGiranManager - Rotated out Syldar (ID: 268516175)
[L2jMobius ScheduledThread 2] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopGiranManager - Rotated out Bravorwyn (ID: 268510236)
[L2jMobius ScheduledThread 11] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopGiranManager - Rotated out Azislith (ID: 268513410)
[L2jMobius ScheduledThread 77] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopRunaManager - Rotated out Рхуниррим (ID: 268511449)
[L2jMobius ScheduledThread 36] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopGiranManager - Rotated out Cynmorn (ID: 268513404)
[L2jMobius ScheduledThread 14] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopGiranManager - Rotated out Indarvane (ID: 268513134)
[17/04 19:55:28] New maximum connected count of 651!
[L2jMobius ScheduledThread 58] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopGiranManager - Rotated out Faeronbore (ID: 268511972)
[L2jMobius ScheduledThread 49] INFO org.l2jmobius.gameserver.ghostservices.ghostshops.GhostShopRunaManager - Rotated out Ваелумиус (ID: 268515751)
[17/04 19:55:33] New maximum connected count of 653!
[17/04 19:55:36] New maximum connected count of 654!
[17/04 19:55:37] New maximum connected count of 655!
[17/04 19:55:39] New maximum connected count of 656!
This is what the console says and continues to increase the maximum online...
-
And the most interesting thing is, the database only lists 150 ghost shops and 30 runners. But in fact, there are already over 1,000 of them in the game... and the number is growing.
-
I also noticed that if you try to sell several items to a merchant, nothing happens. If you sell one item at a time, everything is fine. I don't think that's how it should be.
-
I pushed a fix to the repo. Shops and wanderers are now fully removed when there time is up.
No sure about the merchant issue. The ghosts do not touch that part of the core.
-
I pushed a fix to the repo. Shops and wanderers are now fully removed when there time is up.
No sure about the merchant issue. The ghosts do not touch that part of the core.
Everything works like clockwork now! A very good solution for servers with low online traffic. Thanks for your work.
It would also be great to introduce combat characters who run around the locations and level up. And you can PvP or PK with them. ))) But that's just a rant.
-
A new problem has arisen. I set Max_Batches to 100, and I have a total of 900+ merchants and walking customers. When it's time to replace merchants and walking customers, they are deleted faster than they are replaced, and eventually, within 24 hours, the number drops from 900+ to 150-250. The settings require a minimum of 1 minute before adding a new merchant. This is a lot... they delete faster than they add new ones.
-
I changed the value Respawn_Delay=1 to Respawn_Delay=0.01 and accordingly in the kernel I also changed the value to double, but it did not help, the deletion occurs the same way, and there are practically no new additions.
-
I changed the value Respawn_Delay=1 to Respawn_Delay=0.01 and accordingly in the kernel I also changed the value to double, but it did not help, the deletion occurs the same way, and there are practically no new additions.
Wow 900+. I can honestly say I never tried that many. Think around 300 was the most I ever tried. I am surprised most of them spawned. There is a location aware method in the code that keeps a little separation between players and other ghosts. They will try to find an open spot 3 times and then they give up. You could be running into a situation where there are many not finding a spot and never spawning. That kills the schedule replacement so over time the server is find a balance. If you get enough of those the population number will drop. I bet you are seeing a fair amount of tried 3 times and failed messages in the log.
-
Wow 900+. I can honestly say I never tried that many. Think around 300 was the most I ever tried. I am surprised most of them spawned. There is a location aware method in the code that keeps a little separation between players and other ghosts. They will try to find an open spot 3 times and then they give up. You could be running into a situation where there are many not finding a spot and never spawning. That kills the schedule replacement so over time the server is find a balance. If you get enough of those the population number will drop. I bet you are seeing a fair amount of tried 3 times and failed messages in the log.
In this situation, there's a solution: eliminate character replacement altogether. They will only be replaced after the character has sold everything they were selling.
-
Any chance this system can be done only on datapack using listeners?
-
Any chance this system can be done only on datapack using listeners?
In theory, Yes.
The system is mostly self contained as it is. The only part I am not sure about it the purging of old data from the offline trade tables in the even of a server crash. If the "OFFLINE_GHOST" are not removed before the core's native offline shops they will spawn. I guess in the Init() they could be purged and no one would really know as the game server would not be connected to the login server yet.
I have been out of the L2 scene for a long time and I am new to Mobius. Still getting a handle on the changes and the massive refactor and optimizations that have been done.
I will certainly look into it make this more of a datapack module to get it out of the core.
-
In this situation, there's a solution: eliminate character replacement altogether. They will only be replaced after the character has sold everything they were selling.
See the first post regarding major changes made.
-
Any chance this system can be done only on datapack using listeners?
As requested I converted the GhostServices to a standalone module. Even the config is contained in the module folder.
Drop the GhostService folder in the data/scripts/custom folder.
Edit the GhostServices/config/GhostServices.ini to enable the shops and wanderers (set to false by default).
Start the server as normal.
Should make much easier to test with other chronicles.
Updated the original post with new link to the repo.
-
As requested I converted the GhostServices to a standalone module. Even the config is contained in the module folder.
Drop the GhostService folder in the data/scripts/custom folder.
Edit the GhostServices/config/GhostServices.ini to enable the shops and wanderers (set to false by default).
Start the server as normal.
Should make much easier to test with other chronicles.
Updated the original post with new link to the repo.
You did more than what I expected :D
Updated so it somewhat follows https://l2jmobius.org/forum/index.php?topic=6556.0 and https://l2jmobius.org/forum/index.php?topic=13048.0 if you are ok with it.
Some variables could be static and not be re-instantiated in methods, but my time was limited.
https://limewire.com/d/yYyXd#fIRNdfEgwf
-
You did more than what I expected :D
Updated so it somewhat follows https://l2jmobius.org/forum/index.php?topic=6556.0 and https://l2jmobius.org/forum/index.php?topic=13048.0 if you are ok with it.
Some variables could be static and not be re-instantiated in methods, but my time was limited.
https://limewire.com/d/yYyXd#fIRNdfEgwf
Thanks for sharing the programing style. I will work to get the code cleaned up to match this standard.
I am find with the switch from GPLv3 to MIT.
-
Fixed an issue where the shops respawn delay was using minutes instead of seconds.
Lots of code cleanup to keep in line for l2JMobius code standards.
-
I create a very simple no frills tool for editing the shopitems.xml file.
See the link in the original post.
From the ReadMe:
The ghost shop items are in the GhostServices/data/shopitems.xml.
To make it easier to edit, add and remove items from the list, I created this simple editor.
Run the "L2J_Mobius_Shop_Editor.jar".
Click the "Browse XML" button in the top left.
Select your XML file (Optional: Make a backup first).
The item will be listed in the left panel.
Select an item and the min/max counts, buy low/high, sell low/high and level values will be displayed.
Make you changes and click the Save Changes to XML button.
You can also Add and Remove items using the buttons on the bottom left.
To remove, select and item and click the remove button. You will get a confirmation.
To Add, click the add button.
Enter the item id, Name, and select the category from the dropdown.
This is add it to the list.
Now select the new item and populate the min/max counts, buy low/high, sell low/high and level values.
Click the Save Changes to XML button to update the file.
-
I noticed that when I try to use the Recall command on traders through the admin panel, they just disappear from the game. How to fix this?
-
Since we use java 25,
For xml editor you should replace it "_" as var to other name e.g
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {}
SwingUtilities.invokeLater(() -> new XmlEditor().setVisible(true));
}
And may here too you use
private void updateItemFromForm() {
int row = itemTable.getSelectedRow();
if (row != -1) {
Item sel = itemDataList.get(row);
When you have it itemTable.setAutoCreateRowSorter(true); so for it I think you should convert the indice
private void updateItemFromForm() {
int viewRow = itemTable.getSelectedRow();
if (viewRow != -1) {
int modelRow = itemTable.convertRowIndexToModel(viewRow);
Item sel = itemDataList.get(modelRow);
sel.mincount = txtMin.getText();
sel.maxcount = txtMax.getText();
sel.buylow = txtBuyL.getText();
sel.buyhigh = txtBuyH.getText();
sel.selllow = txtSellL.getText();
sel.sellhigh = txtSellH.getText();
sel.level = txtLvl.getText();
}
} is just a idea may works better
-
I noticed that when I try to use the Recall command on traders through the admin panel, they just disappear from the game. How to fix this?
You don't. The traders do have a character record in the DB but there are not a full blown character. Add to that, they are running a stripped down client-less method.
If you want to change the random spawn locations. Look in the GhostShopManager.jave file. In the createGhostShopRandom() are the X Min/Max and Y Min/Max that stets up the various box locations. Just take a character and do a /loc command at the opposite corners of whatever box you want to create.
-
Since we use java 25,
For xml editor you should replace it "_" as var to other name e.g
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {}
SwingUtilities.invokeLater(() -> new XmlEditor().setVisible(true));
}
And may here too you use
private void updateItemFromForm() {
int row = itemTable.getSelectedRow();
if (row != -1) {
Item sel = itemDataList.get(row);
When you have it itemTable.setAutoCreateRowSorter(true); so for it I think you should convert the indice
private void updateItemFromForm() {
int viewRow = itemTable.getSelectedRow();
if (viewRow != -1) {
int modelRow = itemTable.convertRowIndexToModel(viewRow);
Item sel = itemDataList.get(modelRow);
sel.mincount = txtMin.getText();
sel.maxcount = txtMax.getText();
sel.buylow = txtBuyL.getText();
sel.buyhigh = txtBuyH.getText();
sel.selllow = txtSellL.getText();
sel.sellhigh = txtSellH.getText();
sel.level = txtLvl.getText();
}
} is just a idea may works better
I am sure that would be better. I knocked that out in about 20 minutes and did not put any polish on it. Had some people ask about an easy way to edit the shops XML and that's what I came up with. Personally I have the data in a SQL database and built the XML output using SQL procedures, but I know not everyone is fluent in SQL.
Thanks for taking the time to write up the suggestion.
-
I created a version of the ghost services for Interlude.
Wish there was a way to add multiple chronicle tags to a post. It there is I did not see it.