|
Scarn Apprentice
Joined: 24 Jul 2005 Posts: 137
|
Posted: Sat Aug 02, 2014 12:09 pm
DDE/COM using google chrome. |
My MUD has a website that displays current online members. Is there a way I can use a DDE or COM function to access this page and save the information held on it to a variable?
|
|
|
|
Daern Sorcerer
Joined: 15 Apr 2011 Posts: 809
|
|
|
|
Scarn Apprentice
Joined: 24 Jul 2005 Posts: 137
|
Posted: Sun Aug 03, 2014 5:30 am |
Thanks Daern, I had a search on the forums and to be honest wasn't too sure what I was searching for.
|
|
|
|
Scarn Apprentice
Joined: 24 Jul 2005 Posts: 137
|
Posted: Sun Aug 03, 2014 7:24 am |
So I've had a play around, I'm not the greatest scripter but I do have a knowledge of VB and C++, never really looked into lua until now. So far I have come up with this, it only returns the name of the first player on the list. Am I using the right method to loop it?
Code: |
if not http then http = require("socket.http") end
local page = http.request("http://www.t2tmud.org/wholist.php")
repeat
local players = string.match(page,".userclick..(%w+)..event")
until string.match(page,"Total users")
zs.print("Players online: " .. players) |
Another thing, when I figure out how to get the loop working, I'll just be overwriting the player variable, I should really be using an ADDITEM equivalent. |
|
|
|
Scarn Apprentice
Joined: 24 Jul 2005 Posts: 137
|
Posted: Sun Aug 03, 2014 12:44 pm |
Well, I finished it and it works. Grabs the list of online players and saves it to a CMUD variable.
Code: |
if not http then http = require("socket.http") end
page = http.request("http://t2tmud.org/wholist.php")
numberonline = string.match(page, "Total users...td..td.align..right..(%d+)")
numberonline = tonumber(numberonline)
numberonline = numberonline - 1
page = http.request("http://t2tmud.org/who.php")
online = string.match(page, "%[(.+)%]")
a = {}
i = 1
repeat
a[i] = string.match(online, "..race...%w+...level..%d+..name...(%w+)")
online = string.gsub(online, a[i], "")
i = i + 1
until i > numberonline
zs.var.Test = (a) |
Issue is it takes about 4-5 seconds to run, during which time CMUD freezes, so unfortunately I won't be able to use it as intended. :( |
|
|
|
Daern Sorcerer
Joined: 15 Apr 2011 Posts: 809
|
Posted: Sun Aug 03, 2014 5:01 pm |
Try throwing in a zs.wait(0) at the start to run it in a different thread. Not sure if that works with Lua scripts though...
|
|
|
|
Scarn Apprentice
Joined: 24 Jul 2005 Posts: 137
|
Posted: Mon Aug 04, 2014 5:42 am |
Works, thanks.
|
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Tue Aug 05, 2014 3:06 am |
It is unfortunate that Lua runs in CMUD's main thread. There is no way to separate them so yes, there will be a delay. One thing you can do is run your code against Chrome in an external app (you can use the .NET framework) then either use Luacom to connect to it or, simply, use CMUD COM facilities. I've found that if I use the latter, CMUD does not show a significant hang time, perhaps because CMUD spins off its COM code.
|
|
_________________ Sic itur ad astra. |
|
|
|
Scarn Apprentice
Joined: 24 Jul 2005 Posts: 137
|
Posted: Tue Aug 05, 2014 7:18 am |
ooh this is interesting, are external apps easy enough to use or would I be better off programming my own c# application to get the information? I've also set up this script in MUSHclient, so MUSH does all the work and updates it to a text file. Then I can just grab the info with READ. Means I still have a use for MUSH :P
|
|
|
|
Anaristos Sorcerer
Joined: 17 Jul 2007 Posts: 821 Location: California
|
Posted: Tue Aug 05, 2014 7:44 am |
You can write C# apps that are COM visible and registered for COM interop.
There are two ways you can interact with CMUD. One way is to execute a method and wait for the returned output (I usually only have one method - execute- which takes a JSON string as parameter. I then decode the requests, execute them, and return a JSON string as output). The other way is to treat CMUD as COM server/client and access it in your C# app. Both methods of access have their advantages. The second method is more flexible since it can run independently, but it's a bit more technical (One usage would be to have the client fire triggers that send data to the app and have the app push data to the client while the user is otherwise engaged). As an example, I update my inventory database using the first method. When there is any inventory movement, invmon outputs a string to the client, a trigger captures the string and invokes the execute method of the inventory manager. The inventory manager has a thread that interacts with MS SQL Server so the updates don't impact the client at all. This works for any type of database interaction, though you do want the client to wait in the case where it is pulling data from the database server.
Here is a two C# snippets that show how the inventory database is updated:
First the update request from the user:
Code: |
public void MoveItem(Int64 objectID, Int64 containerID)
{
if (DataStructures.Items != null)
{
InvItem item;
if ((item = DataStructures.Items.AsParallel()
.FirstOrDefault(i => i.ObjectID == objectID)) != null)
{
item.ContainerID = containerID;
DataStructures.ItemThreadManager.EnqueueTask(() => UpdateItem(item));
}
}
}
|
Then the actual update:
Code: |
private void UpdateItem(InvItem i)
{
string proc = "inv_update_new";
string connStr = Properties.Settings.Default.equConnStr;
using (SqlConnection conn = new SqlConnection(connStr))
{
SqlCommand cmd = new SqlCommand(proc, conn);
cmd.Parameters.AddWithValue("user", User);
cmd.Parameters.AddWithValue("id", i.ObjectID);
cmd.Parameters.AddWithValue("cid", i.ContainerID);
cmd.Parameters.AddWithValue("room", -1);
cmd.CommandType = CommandType.StoredProcedure;
try
{
conn.Open();
cmd.ExecuteNonQuery();
}
catch (SqlException e)
{
DataStructures.ErrorMsg = e.Message;
}
}
}
|
|
|
_________________ Sic itur ad astra. |
|
|
|
|
|