Page 33 of 46

Re: rock5's "fastLogin Revisited"

Posted: Fri Jan 31, 2014 7:06 pm
by ZZZZZ
You have a shortcut link to client.exe called 'myrom' in your script/rom folder right? Just guessing at stuff here xD

Re: rock5's "fastLogin Revisited"

Posted: Fri Jan 31, 2014 11:10 pm
by noobbotter
Sure do. If I browse to it and double click it it will launch the client properly. And the interesting thing is that if it were not there, the error I get would be different. But both errors say it's not there. It has me completely baffled.

Re: rock5's "fastLogin Revisited"

Posted: Sat Feb 01, 2014 12:05 am
by rock5
@ZZZZZ I'll look into it. Just to make sure I understand you correctly, you want to use an extra value as a label for the buttons. For instance, have an extra value added to the account table and use it as a label for the buttons. Is that right?

@noobbotter, that's some great deductive work you did.

Maybe the first error is not that the link doesn't exist but the file that it points to. But it works because you tested it. Everything I've tried worked. That includes; creating a link to a file with spaces in it, removing the quotes from the link address, removing the "Start in" value from the link, etc.

How did you create the link? Did you modify it in any way? What version of Windows are you using?

Here is another idea. 'S' is a pretty high letter for a drive. Is that a network shortcut? I know Windows has an issue sometimes with network locations until you visit them in Explorer. For instance if you open explorer, for the first time, you might see red cross through the network mapped drive until you click on them to view the contents. I've had issues with Classic Media Player not being able to resume the last file played because of this. I've had to create a batch file that renews all my connections at start up. Could this be your problem? If you visit the location first do you still get that error? With all your testing I doubt this is the case but it's worth mentioning.

Re: rock5's "fastLogin Revisited"

Posted: Sat Feb 01, 2014 2:02 am
by ZZZZZ
Yep, exactly that R5. Would be good in general to have a label, makes keeping track of characters a lot easier.

Re: rock5's "fastLogin Revisited"

Posted: Sat Feb 01, 2014 6:18 am
by rock5
The problem is, if we want to make this permanently part of the addon, how are we going to make it work with the Server, Account, AccountServer display option? I don't think we can just make it an extra setting because you might not want to add a label to every single account.

We could make it so that if there is a label then it overrides the display setting. What do you think of that? What I mean is, if the buttons are currently showing AccountServer info then any accounts that don't have a label will show the Account Server info but if there is a label then it shows the label. So that means if you Shift-Click the buttons it will only change the display for buttons that don't have labels. The buttons with labels will always show the labels. What do you think?

Re: rock5's "fastLogin Revisited"

Posted: Sat Feb 01, 2014 8:31 am
by Agrozet
Hi,
can someone please me on this script practically demonstrate how to set switching.
I can not understand how to set up.

I have this set up,

fastlogin - accountlogin.lua, logindialog.lua

userfunction_LoginNextChar.lua - SetCharList

AT.xml script switches

My English is bad, sorry

Code: Select all

Loaded waypoint path /Xaviera/VineDaily/StartVine_char.xml
No return path with default naming /Xaviera/VineDaily/StartVine_char_return.xml found.
We use the normal waypoint path /Xaviera/VineDaily/StartVine_char.xml now.
Waypoint #51 is closer then #1. Hence we start with waypoint #51.
GM detection started
GM detection started
Moving to waypoint #51, (-6718, -3710)
We where running for 24 seconds.
Use MACRO: Executing RoMScript "}LoginNextToon=true;a={".
Resting for 2 seconds.
Resting finished after 2 seconds.
Use MACRO: Executing RoMScript "Logout();".
Player address changed: 0x4D3A5A00
The game client did not crash.
1:47pm - [string "..."]:9: attempt to perform arithmetic on a string value

Code: Select all

<?xml version="1.0" encoding="utf-8"?><waypoints type="TRAVEL">
<onload>
				
<![CDATA[
         startGMDetect()
   ]]>

	function relog()
   
   SetCharList({
	{account=3, chars= {1,2}},              -- Juka
	{account=4, chars= {1}},                 -- Kuka
    })
   
   -- My game crashes after reloging 7 times so make it restart the game every 7 relogs.
   	-- SetRestartClientSettings(7, "rom4u")
	-- SetRestartClientSettings(4, "Rom");

   -- After finishing this script do dailies but have each client do different dailies.
   	if IsLastChar() then
      -- if getAcc() == 6 then -- End of first CharList
        ChangeChar() -- First char of first list.
        loadProfile()
        loadPaths("VineDaily/StartVine_char")
      
      
   else
      -- It's not the last character so continue with the list and reload this file.
	
	LoginNextChar()
      	loadProfile()
	-- loadPaths(__WPL.FileName)
      	loadPaths("VineDaily/StartVine_char")
   end
end

	

	--[[ Objects by ID for multi-language use ]]--
			fiona 		= GetIdName(118070) 		-- NPC "Fiona Andus"
			defenses 	= GetIdName(424176) 		-- Quest "The Elves' Defenses"
			vine 		= 118193 			-- Object "Protector Vine"

</onload>
	<!-- #  1 --><waypoint x="-6322" z="-3913" y="173">
		travelTo("Jinners")
      	</waypoint>
	<!-- #  2 --><waypoint x="12873" z="1955" y="64">player:mount()	</waypoint>
	<!-- #  3 --><waypoint x="12897" z="2167" y="67">	</waypoint>
	<!-- #  4 --><waypoint x="12822" z="2244" y="66">	</waypoint>
	<!-- #  5 --><waypoint x="12736" z="2418" y="60">	</waypoint>
	<!-- #  6 --><waypoint x="12713" z="2470" y="74">	</waypoint>
	<!-- #  7 --><waypoint x="12620" z="2594" y="84">	</waypoint>
	<!-- #  8 --><waypoint x="12336" z="2625" y="82">	</waypoint>
	<!-- #  9 --><waypoint x="12085" z="2654" y="87">	</waypoint>
	<!-- # 10 --><waypoint x="11774" z="2679" y="89">	</waypoint>
	<!-- # 11 --><waypoint x="11500" z="2674" y="139">	</waypoint>
	<!-- # 12 --><waypoint x="11297" z="2790" y="140">	</waypoint>
	<!-- # 13 --><waypoint x="11078" z="3013" y="138">	</waypoint>
	<!-- # 14 --><waypoint x="10917" z="3242" y="140">	</waypoint>
	<!-- # 15 --><waypoint x="10784" z="3506" y="143">	</waypoint>
	<!-- # 16 --><waypoint x="10590" z="3914" y="147">	</waypoint>
	<!-- # 17 --><waypoint x="10552" z="4283" y="188">	</waypoint>
	<!-- # 18 --><waypoint x="10567" z="4465" y="210">	</waypoint>
	<!-- # 19 --><waypoint x="10551" z="4731" y="218">	</waypoint>
	<!-- # 20 --><waypoint x="10522" z="4996" y="218">	</waypoint>
	<!-- # 21 --><waypoint x="10478" z="5238" y="213">	</waypoint>
	<!-- # 22 --><waypoint x="10435" z="5416" y="220">	</waypoint>
	<!-- # 23 --><waypoint x="10358" z="5446" y="222"  tag="fiona">		
		player:target_NPC(fiona)

		if getQuestStatus(defenses) == "complete" then
			CompleteQuestByName(defenses)
			cprintn(cli.lightblue,"=-=-= "..player.Name.." - "..RoMScript("Daily_count()").." daily quests completed. =-=-=")
		end

		if RoMScript("Daily_count()") == 10 then
			cprintf(cli.lightblue,"Completed max number 10 of daily quests.\n")
			changeProfileOption("HARVEST_DISTANCE", 120)
			goto_wp("fionaReturn")
		else
			if getQuestStatus(defenses) == "not accepted" then
				AcceptQuestByName(defenses)
			end
		end
	</waypoint>
	<!-- # 24 --><waypoint x="10352" z="5444" y="223">	</waypoint>
	<!-- # 25 --><waypoint x="10294" z="5609" y="220" tag="vines">	
		if 180 > settings.profile.options.HARVEST_DISTANCE then changeProfileOption("HARVEST_DISTANCE", 180) end
		while getQuestStatus(defenses) == "incomplete" do
			player:target_Object(vine, 500)
		end
	</waypoint>
	<!-- # 26 --><waypoint x="10322" z="5577" y="208">	</waypoint>
	<!-- # 27 --><waypoint x="10303" z="5576" y="220">
		goto_wp("fiona")
	</waypoint>

<!-- Waypoints to run from Fiona to Jinners Camp (best if Recall is on cd) -->
	<!-- #  28 --><waypoint x="10358" z="5446" y="222" tag="fionaReturn">
		player:mount()
	</waypoint>
	<!-- #  29 --><waypoint x="10435" z="5416" y="220">	</waypoint>
	<!-- #  30 --><waypoint x="10478" z="5238" y="213">	</waypoint>
	<!-- #  31 --><waypoint x="10522" z="4996" y="218">	</waypoint>
	<!-- #  32 --><waypoint x="10551" z="4731" y="218">	</waypoint>
	<!-- #  33 --><waypoint x="10567" z="4465" y="210">	</waypoint>
	<!-- #  34 --><waypoint x="10552" z="4283" y="188">	</waypoint>
	<!-- #  35 --><waypoint x="10590" z="3914" y="147">	</waypoint>
	<!-- #  36 --><waypoint x="10784" z="3506" y="143">	</waypoint>
	<!-- #  37 --><waypoint x="10917" z="3242" y="140">	</waypoint>
	<!-- #  38 --><waypoint x="11078" z="3013" y="138">	</waypoint>
	<!-- #  39 --><waypoint x="11297" z="2790" y="140">	</waypoint>
	<!-- #  40 --><waypoint x="11500" z="2674" y="139">	</waypoint>
	<!-- #  41 --><waypoint x="11774" z="2679" y="89">	</waypoint>
	<!-- #  42 --><waypoint x="12085" z="2654" y="87">	</waypoint>
	<!-- #  43 --><waypoint x="12336" z="2625" y="82">	</waypoint>
	<!-- #  44 --><waypoint x="12620" z="2594" y="84">	</waypoint>
	<!-- #  45 --><waypoint x="12713" z="2470" y="74">	</waypoint>
	<!-- #  46 --><waypoint x="12736" z="2418" y="60">	</waypoint>
	<!-- #  47 --><waypoint x="12822" z="2244" y="66">	</waypoint>
	<!-- #  48 --><waypoint x="12897" z="2167" y="67">	</waypoint>
	<!-- #  49 --><waypoint x="12873" z="1955" y="64">
	     travelTo("Heffner")
      	</waypoint>
	<!-- #  50 --><waypoint x="-6368" z="-3873" y="165">	</waypoint> 
	<!-- #  51 --><waypoint x="-6718" z="-3710" y="172">
	printf("We where running for %s seconds.\n", os.difftime(os.time(),player.BotStartTime_nr) - player.Sleeping_time );
	sendMacro("}LoginNextToon=true;a={");player:rest(2)
	sendMacro("Logout();"); waitForLoadingScreen() -- wait for next character to load
         
         -- Re-initialize player
        player = CPlayer.new();
	settings.load(); 
	printf("Loaded character " .. player.Name .. ""/n);
        settings.loadProfile("Juka","Kuka");
	-- settings.loadProfile("Juka");
        yrest (4000)
        loadPaths("VineDaily/StartVine_char")
	relog()
	</waypoint>
	<!-- #  52 --><waypoint x="-6534" z="-3801" y="166">	</waypoint>
	<!-- #  53 --><waypoint x="-6404" z="-3866" y="165">	</waypoint>
	<!-- #  54 --><waypoint x="-6322" z="-3913" y="173">	</waypoint>
</waypoints>

Re: rock5's "fastLogin Revisited"

Posted: Sat Feb 01, 2014 9:22 am
by ZZZZZ
rock5 wrote:The problem is, if we want to make this permanently part of the addon, how are we going to make it work with the Server, Account, AccountServer display option? I don't think we can just make it an extra setting because you might not want to add a label to every single account.
Couldn't you add Label to the 4th CustomLoginButton and make it so that

Code: Select all

if fastLoginButtonDisplay = "Label" then
if Label ~= "" then 
show Label 
else 
show AccoutServer 
end

Re: rock5's "fastLogin Revisited"

Posted: Sat Feb 01, 2014 9:23 am
by rock5
@Agrozet

Firstly, make sure they are all up to date.

Secondly, do not modify userfunction_loginnextchar.lua. From the way you listed it, it looked like you edited it.

Thirdly, don't use LoginNextToon=true. That is old code. Use SetCharList and LoginNextChar() only.

Fourthly, the main use for IsLastChar() is if you want to run all your characters through 1 waypoint and when they are all finished, you want to run them all through another waypoint. You only have one waypoint file name listed so I don't think you need to use IsLastChar().

This is a basic relog function

Code: Select all

function relog()
   SetCharList({
   {account=3, chars= {1,2}},              -- Juka
   {account=4, chars= {1}},                 -- Kuka
    })
   LoginNextChar()
   loadProfile()
   loadPaths(__WPL.FileName)
end
Note: loadProfile(), by default, will try to load a profile with the same name as the character or if that doesn't exist it will try to load a profile called userdefault.xml. If neither exit is will error.
Note 2: __WPL.FileName is a variable the holds the name of the current waypoint file so loadPaths(__WPL.FileName) will reload the same waypoint file.

Waypoint 51 should look like this

Code: Select all

 <!-- #  51 --><waypoint x="-6718" z="-3710" y="172">
   printf("We where running for %s seconds.\n", os.difftime(os.time(),player.BotStartTime_nr) - player.Sleeping_time );
   relog()
   printf("Loaded character " .. player.Name .. ""/n);
   </waypoint>

Re: rock5's "fastLogin Revisited"

Posted: Sat Feb 01, 2014 9:32 am
by rock5
ZZZZZ wrote:Couldn't you add Label to the 4th CustomLoginButton and make it so that

Code: Select all

if fastLoginButtonDisplay = "Label" then
if Label ~= "" then 
    show Label 
else 
    show AccoutServer 
end
But then if you set it to display the labels and there isn't a label what do you display; Account, Server or AccountServer?

Of course if we do override the display, if there is a label, then how do we display the server/account info if we need to see it?

So there is still a bit to think through before we can implement this feature.

Re: rock5's "fastLogin Revisited"

Posted: Sat Feb 01, 2014 9:50 am
by ZZZZZ
As for display when Label == "" I would use AccountServer. It shows both of the variables that you would need.

Can the option of Label not be implemented in the same manner as the current 'swap' system? Where you Shift-Left Click a button to change what is being displayed?

Code: Select all

function CustomLoginButton_ToggleDisplay()
	fastLoginButtonDisplay = fastLoginButtonDisplay + 1
	if fastLoginButtonDisplay > 3 then
		fastLoginButtonDisplay = 1
	end
changed to

Code: Select all

function CustomLoginButton_ToggleDisplay()
	fastLoginButtonDisplay = fastLoginButtonDisplay + 1
	if fastLoginButtonDisplay > 4 then
		fastLoginButtonDisplay = 1
	end
to keep the cycle going around and adding in another option above it with the

Code: Select all

	elseif fastLoginButtonDisplay == 4 then -- Button Label
		for i=1, 108 do
			button = getglobal("CustomLoginButton"..i);
			local Name, Pass, Server, Label = ReturnLoginID(i);
			if ( Name ~= nil ) and ( Name ~= "" ) and ( Name ~= " " ) then
				Label = Label or "nil" -- in case Label is not specified
                                if Label ~= nil then
				   if string.len(Label) > 16 then
					button.tooltip = Label
					Name = string.sub(Label, 1, 16)
				   else
					button.tooltip = nil
				   end
                                else
                                   ?? fastLoginButtonDisplay = 1 ??         -- Maybe? Not sure.
                                   ?? CustomLoginButtonsDisplay_Update() ??
                                end
				button:SetText(Label);
			else
				button:Hide();
			end
		end
Totally guessing here, lol.

Re: rock5's "fastLogin Revisited"

Posted: Sat Feb 01, 2014 11:19 am
by rock5
ZZZZZ wrote:As for display when Label == "" I would use AccountServer. It shows both of the variables that you would need.
I don't like just defaulting to that. What if the user prefers to use just Account because they only play on 1 server and they use similar account name that, if the server is included, then it would make it impossible to tell which is which because the account would get truncated. Example: say they want to use some labels and they have some accounts they don't want to label called account1, account2 and account3. If you force them to use AccountServer their display might look like this.

Code: Select all

Label1
Label2
accoun/server
accoun/server
accoun/server
Obviously this user would prefer to display their non labeled account with just Account

Code: Select all

Label1
Label2
account1
account2
account3
That's why I think the labels should not be a 4th display option. I think labels should override the user selected display and the accounts without labels should display as the user selected. I noticed that I have the account and server info in the tooltip if they don't fit. I can probably also add them to the tooltip of accounts with labels so if you need that info it's there. That sounds like a plan.

Re: rock5's "fastLogin Revisited"

Posted: Sat Feb 01, 2014 11:34 am
by ZZZZZ
So instead add another function with an extra option at the top that asks 'Show Label's = "true/false"'. Then if true and Label ~= nil then display Label else display "fastLoginButtonDisplay"?

** off to bed, will look at this in the morning ^.^

Re: rock5's "fastLogin Revisited"

Posted: Sat Feb 01, 2014 11:44 am
by rock5
That pretty much sounds like what I suggested (Label ~= nil then display Label else display "fastLoginButtonDisplay") but with an extra option. I could add the option but the user is already making a choice to have a label when they add it so you don't need another option to show the label. What would be the point of adding labels if you don't want to show them?

Re: rock5's "fastLogin Revisited"

Posted: Sat Feb 01, 2014 8:17 pm
by ZZZZZ
yeh good point, but will you still make it so you can rotate through the AccountServer, Account and Server views with Shift-Left Click? I think you should still be able to.

Re: rock5's "fastLogin Revisited"

Posted: Sat Feb 01, 2014 10:16 pm
by rock5
The idea is that the not labeled accounts will still be able to rotate the different displays. The labeled ones wont change. And I think the tooltip on the labeled ones will include what would have been displayed if it didn't have a label.

Re: rock5's "fastLogin Revisited"

Posted: Sun Feb 02, 2014 3:59 am
by Agrozet
Thank rock5, script works, I just gave tag=""
Char stood at waypoint 51 and did not go away

Code: Select all

<!-- #  51 --><waypoint x="-6718" z="-3710" y="172">
	relog()
	goto_wp("aa")
        </waypoint>
	<!-- #  52 --><waypoint x="-6534" z="-3801" y="166"	tag="aa">  </waypoint>
	<!-- #  53 --><waypoint x="-6404" z="-3866" y="165">	</waypoint>
	<!-- #  54 --><waypoint x="-6322" z="-3913" y="173">	</waypoint>
</waypoints>

Re: rock5's "fastLogin Revisited"

Posted: Sat Feb 08, 2014 9:23 am
by ZZZZZ
Ok well I finally got around to doing this whole 'Label' thing with loginxml and surprisingly....I actually got it to work O.o Not that there was much to change though.
If you have anything in the variable Label it will always show it on the button, with the Name/Server in the tooltip. If Label = "" it'll display what ever you have 'fastLoginButtonDisplay' set to in the user options. (Sorta want to make it so if you Shift-Left Click and it'll still cycle between the modes but for now I couldn't be bothered lol)

Re: rock5's "fastLogin Revisited"

Posted: Tue Feb 18, 2014 1:00 pm
by noobbotter
I was wondering how I would go about setting my CharList dynamically? For instance, say I have 3 groups of characters. Depending on certain things I may or may not want to run the group through a certain waypoint. I have a variable for each group to indicate whether or not I want to run this particular waypoint: g1 = true means I will run group 1. g2 = false means I will not run group 2.

Now, the big question is how can I go through and do a table insert into my CharList table for each group that is true?

I'm thinking something like:

Code: Select all

CharList = {}
if g1 == true then
   table.insert(CharList,"{account=7 , chars= {1,2,3,4,5,6,7,8}},")
end
if g2 == true then
   table.insert(CharList,"{account=19 , chars= {1,2,3,4,5,6,7,8}},")
end
I just don't think the above would work because of the numbers of brackets in the CharList. I'm not sure how to work around those.

Code: Select all

CharList = {{
		{account=7 , chars= {1,2,3,4,5,6,7,8}},
	   {account=19 , chars= {1,2,3,4,5,6,7,8}},
	   {account=12 , chars= {1,2,3,4,5,6,7,8}},
	   {account=24 , chars= {1,2,3,4,5,6,7,8}},
	}}
Any ideas?

Re: rock5's "fastLogin Revisited"

Posted: Tue Feb 18, 2014 3:01 pm
by noobbotter
I think I figured it out. I'll have to test it at home, but using micromacro by itself (without the rom client) it looks like it is going to work:

-- I'm saving true or false to a file based on user selections for each group I have available. (so for groups 1 through 4, the file would end up with 4 words, each of the 4 being either "true" or "false", each with a semicolon separating them). Then after all selections are made, The script will read them in to the raw variable then:

Code: Select all

subtable1 = {}
		subtable2 = {}
				
		local g1,g2,g3,g4 = string.match(raw,"(.*);(.*);(.*);(.*)") 
		if g1 == "true" then
			subtable2 = {account = 7 , chars= {1,2,3,4,5,6,7,8}}
			subtable1 = {subtable2}
			table.insert(CharList,subtable1)
		end
		if g2 == "true" then
			subtable2 = {account = 19 , chars= {1,2,3,4,5,6,7,8}}
			subtable1 = {subtable2}
			table.insert(CharList,subtable1)
		end
		if g3 == "true" then
			subtable2 = {account = 12 , chars= {1,2,3,4,5,6,7,8}}
			subtable1 = {subtable2}
			table.insert(CharList,subtable1)
		end
		if g4 == "true" then
			subtable2 = {account = 24 , chars= {1,2,3,4,5,6,7,8}}
			subtable1 = {subtable2}
			table.insert(CharList,subtable1)
		end
Looking at the output of this if I do a table.print looks the same as when I do a table.print of my statically entered CharList.

Having figured this out, I'll be able to choose which groups I want to run on a particular daily file and have the loadnext file that does my logging and loading of the next character read the file to see what the currently selected character list looks like. This way if I only want to run certain groups of characters, I don't have to modify the loadnext file all the time.

**EDIT:
I just noticed a difference, so this still isn't quite right. Gotta work on it a bit more.

**Edit2:

Ok, I double checked it and I got it right this time... I think. It looks right anyway.

Code: Select all

function readCharList()
		
		filename = getExecutionPath() .. "/logs/Elves/Dailies.log"
		local file, err = io.open(filename, "r");
		if( not file ) then
			error(err, 0);
		end
		local raw=file:read()
		file:close()
		subtable = {}
				
		local g1,g2,g3,g4 = string.match(raw,"(.*);(.*);(.*);(.*)")
		if g1 == "true" then
			subtable1 = {account = 7 , chars= {1,2,3,4,5,6,7,8}}
			table.insert(subtable,subtable1)
		end
		if g2 == "true" then
			subtable2 = {account = 19 , chars= {1,2,3,4,5,6,7,8}}
			table.insert(subtable,subtable2)
		end
		if g3 == "true" then
			subtable3 = {account = 12 , chars= {1,2,3,4,5,6,7,8}}
			table.insert(subtable,subtable3)
		end
		if g4 == "true" then
			subtable4 = {account = 24 , chars= {1,2,3,4,5,6,7,8}}
			table.insert(subtable,subtable4)
		end
		table.insert(CharList,subtable)
	end

Re: rock5's "fastLogin Revisited"

Posted: Tue Feb 18, 2014 8:26 pm
by rock5
There are 2 types of character lists. One has only 1 list with possibly multiple accounts that is intended to be used by one client which will go through them one by one. Example,

Code: Select all

SetCharList({
      {account=7 , chars= {1,2,3,4,5,6,7,8}},
      {account=19 , chars= {1,2,3,4,5,6,7,8}},
      {account=12 , chars= {1,2,3,4,5,6,7,8}},
      {account=24 , chars= {1,2,3,4,5,6,7,8}},
})
The second has multiple lists with the intention of there being a client for each list. Example

Code: Select all

SetCharList({
      {
            {account=7 , chars= {1,2,3,4,5,6,7,8}},
            {account=19 , chars= {1,2,3,4,5,6,7,8}},
      },{
            {account=12 , chars= {1,2,3,4,5,6,7,8}},
            {account=24 , chars= {1,2,3,4,5,6,7,8}},
      }
})
This example of yours
noobbotter wrote:CharList = {{
{account=7 , chars= {1,2,3,4,5,6,7,8}},
{account=19 , chars= {1,2,3,4,5,6,7,8}},
{account=12 , chars= {1,2,3,4,5,6,7,8}},
{account=24 , chars= {1,2,3,4,5,6,7,8}},
}}
looks like it has too many brackets but should still work. It basically looks like a "multiple list" type character list with only one list.

Anyway, the last code you posted looks like it creates a "multi list" list with 4 lists. So a client would only go through 1 account. If you want it to create only one list that 1 client can go through then remove the "subtable1 = {subtable2}" lines and insert subtable2 directly into CharList.