there a way to run and play with lua in a windows os?
Lua compiler for windows
Posted by Metsuro on Sat 19 Jan 2008 03:09 AM — 24 posts, 102,340 views.
See:
http://www.gammon.com.au/files/mushclient/lua5.1_extras/lua5.1.zip
This has the Lua 5.1 executable in it.
http://www.gammon.com.au/files/mushclient/lua5.1_extras/lua5.1.zip
This has the Lua 5.1 executable in it.
ok since i made this thread donno if I should make a second for this next question I am trying to change something from python to lua just to play around a bit but I actually dont know any python soo..
This is the example of how to do what I want to in python, but I'd like to achieve the same thing in lua...
This is the example of how to do what I want to in python, but I'd like to achieve the same thing in lua...
# short testing script which fetches recent market transactions; this only prints out
# the data, it's an exercise to the reader to parse the XML and do something useful
# with the data.
import httplib, urllib
# setup the parameters we will be sending to the webserver; note that all of this
# information is gathered from the API Key page that the user should visit, and
# the characterID is gathered from /account/Characters.xml.aspx
params = urllib.urlencode( {
'characterID': xxx,
'userid': xxx,
'apikey': 'xxx',
} )
# connect to server, POST our request, fairly simple stuff...
headers = { "Content-type": "application/x-www-form-urlencoded" }
conn = httplib.HTTPConnection("api.eve-online.com")
conn.request("POST", "/char/WalletTransactions.xml.aspx", params, headers)
# now get response from server, print out the status code for debugging
response = conn.getresponse()
print response.status, response.reason
# now print the data; at this point you'd want to do XML parsing and do whatever
# else you want... well, after probably doing conn.close below
data = response.read()
print data
# OCD comment placement
conn.close
ok another stupid question this method is not compatible with 5.1 just 5.0? or is it just me... I cant seem to get it to work with the 5.1 but i can with 5.0 this is the error i get in 5.1
> http = require "http"
lua.lua:15: attempt to index global '_LOADED' (a nil value)
stack traceback:
lua.lua:15: in function 'require'
stdin:1: in main chunk
[C]: ?
Ah yes, well that was my initial post done for Lua 5.0.
See this:
http://www.gammon.com.au/forum/?id=7322
Scroll down to "How to get LuaSocket to work".
Also see:
http://www.gammon.com.au/forum/?id=8319
The second post is more recent. If you follow that it should work OK.
See this:
http://www.gammon.com.au/forum/?id=7322
Scroll down to "How to get LuaSocket to work".
Also see:
http://www.gammon.com.au/forum/?id=8319
The second post is more recent. If you follow that it should work OK.
Well ok I got it load a webpage and all but i'm still rather confused on the urlencode, and the connection bits cause I can view the site no problem, but the connecting to it and sending the data for what I want I dont understand I guess.
After ,urking around I found all i needed.
Ok guys I'm sorry if I'm being a bother but... I can view this file through a web browser http://api.eve-online.com/char/CharacterSheet.xml.aspx?userID=1075019&apiKey=crwY4h9679J5ab0py2SL8G9xtOhFB0tLuayoh6aEr5a4iDgwPrUMG7qWpzogZpki&characterID=1097517373
This is my character sheet for eve online. There are a few programs out that can use this information and display it fun way... and what I'm trying to do is mess with this so i can make character backups for myself aswell as help my corp out in the game... only problem is when using luasocket to access the address above and try to print it, it returns nil. But i can use this one and retrieve it just fine. So i'm at a lose... this here is the address to the dev wiki for this api stuff for eve online if anyone wouldn't mind taking a shot at it to help me out. http://wiki.eve-dev.net/Main_Page
This is my character sheet for eve online. There are a few programs out that can use this information and display it fun way... and what I'm trying to do is mess with this so i can make character backups for myself aswell as help my corp out in the game... only problem is when using luasocket to access the address above and try to print it, it returns nil. But i can use this one and retrieve it just fine. So i'm at a lose... this here is the address to the dev wiki for this api stuff for eve online if anyone wouldn't mind taking a shot at it to help me out. http://wiki.eve-dev.net/Main_Page
That is because what you gave isn't a URL: it's a URL with POST parameters.
The URL is:
http://api.eve-online.com/char/CharacterSheet.xml.aspx
The POST parameters are:
userID=1075019
apiKey=crwY4h9679J5ab0py2SL8G9xtOhFB0tLuayoh6aEr5a4iDgwPrUMG7qWpzogZpki
characterID=1097517373
When you make the socket HTTP request, you need to use just the URL portion as the 'url' parameter, and add the parameters one per line as the request body. I think that LuaSocket will set the request method to POST for you.
See:
http://www.tecgraf.puc-rio.br/~diego/professional/luasocket/http.html#request
The URL is:
http://api.eve-online.com/char/CharacterSheet.xml.aspx
The POST parameters are:
userID=1075019
apiKey=crwY4h9679J5ab0py2SL8G9xtOhFB0tLuayoh6aEr5a4iDgwPrUMG7qWpzogZpki
characterID=1097517373
When you make the socket HTTP request, you need to use just the URL portion as the 'url' parameter, and add the parameters one per line as the request body. I think that LuaSocket will set the request method to POST for you.
See:
http://www.tecgraf.puc-rio.br/~diego/professional/luasocket/http.html#request
That's a GET query string, not POST :P and it is a URL. (or URN, URI whatever...)
The EVE API actually prefers POST for most things (and why they couldn't have just used REST, or SOAP, or XML-RPC like sane code monkeys, no-one will ever know) but GET is designed to work for testing.
And, just testing it:
works fine in the python interactive interpreter.
So, LuaSocket is doing Something it shouldn't, or failing to do something it should. The EVE API might be filtering on the UserAgent header, or expecting HTTP/1.1 with Date and Host headers, or an eTag, or Last-Modified header or any of a number of other headers that the python urllib2 library does for you and the LuaSocket might not.
Why does it need to be Lua? (Especially since you don't seem to be planning this as a MUSHclient plugin.)
I was writing my own Python client back when it was in beta but Entity finished his first and feature-wise it blew mine out of the water so I never got around to finishing mine.
(And it's probably not a brilliant idea to share either your basic or full API key like that, particularly if you're in a player corp :P)
The EVE API actually prefers POST for most things (and why they couldn't have just used REST, or SOAP, or XML-RPC like sane code monkeys, no-one will ever know) but GET is designed to work for testing.
And, just testing it:
import urllib2
urllib2.urlopen("...").read()works fine in the python interactive interpreter.
So, LuaSocket is doing Something it shouldn't, or failing to do something it should. The EVE API might be filtering on the UserAgent header, or expecting HTTP/1.1 with Date and Host headers, or an eTag, or Last-Modified header or any of a number of other headers that the python urllib2 library does for you and the LuaSocket might not.
Why does it need to be Lua? (Especially since you don't seem to be planning this as a MUSHclient plugin.)
I was writing my own Python client back when it was in beta but Entity finished his first and feature-wise it blew mine out of the water so I never got around to finishing mine.
(And it's probably not a brilliant idea to share either your basic or full API key like that, particularly if you're in a player corp :P)
As far as I can make out, the Lua interface generates a reasonable HTTP request, even if you combine everything into the URL. I tested it with trying to access a forum page and it worked fine.
However I also confirm that the URL for the Eve Online character did not work. I am not sure exactly why, but they may be checking for certain web browsers and if they don't get it they close the connection.
Luasocket has a more advanced interface, see:
http://www.tecgraf.puc-rio.br/~diego/professional/luasocket/http.html
Using that you can specify your own headers, however you would need to know what it is expecting. A packet sniffer might help in that regards.
However I also confirm that the URL for the Eve Online character did not work. I am not sure exactly why, but they may be checking for certain web browsers and if they don't get it they close the connection.
Luasocket has a more advanced interface, see:
http://www.tecgraf.puc-rio.br/~diego/professional/luasocket/http.html
Using that you can specify your own headers, however you would need to know what it is expecting. A packet sniffer might help in that regards.
Err. Sorry, yeah, I meant get with parameters, not post... although I probably said post because I'm used to sending parameters with post, not get... bleh. :P
well i tried using like
which again didn't work... in the example it uses a header content-type but I'm not exactly sure how to do that using this method.
example was
the params being of course my userid charid and apikey
a = http.request{method="POST", url"http://api.eve-online.com/char/CharacterSheet.xml.aspx?userID=1075019&apiKey=crwY4h9679J5ab0py2SL8G9xtOhFB0tLuayoh6aEr5a4iDgwPrUMG7qWpzogZpki&characterID=1097517373"}which again didn't work... in the example it uses a header content-type but I'm not exactly sure how to do that using this method.
example was
conn.request("POST", "/char/WalletTransactions.xml.aspx", params, headers)the params being of course my userid charid and apikey
A GET request is a standard http request for a document. POST requests need the CGI parameters (everything after the ? in a GET request) to be passed in the body of the message, and in some cases, the presence of a Content-Type: application/x-www-form-urlencoded header.
Python's urllib2 handles that for you transparently.
The API is intended for tool developers. In the documentation they recommend providing a unique User-Agent string so that they can potentially tailor a response (ie if the tool is in the wild and the API is updated, they might keep the old response format for a certain User-Agent string). However CCP being CCP and the EVE API being Garthagk's pet project (and Garthagk no longer being an employee of CCP...) it's entirely possible that not receiving a User-Agent string at all causes something to fail silently.
The point is if you just telnet to api.eve-online.com on port 80 and manually enter the GET query, the connection is terminated before the server sends anything... so the ASP process is dying (or being killed?) before it even gets the opportunity to generate an HTTP response code.
Ok, it turns out that the dead simple example given on the API website (using httplib instead of urllib2) uses HTTP/1.1 and sends the GET string, the (required) Host header and an Accept-encoding header.
The issue might be as simple as api.eve-online.com being a virtual site? Or IIS is configured to drop HTTP/1.0 and HTTP/0.9 connections.
Anyway, using telnet to api.eve-online.com on port 80 I verified that EVE API will respond to:
So, we presume that LuaSocket either doesn't know about HTTP/1.1 or doesn't produce compliant messages (ie missing host header or the HTTP/1.1 tag).
Python's urllib2 handles that for you transparently.
Quote:
I am not sure exactly why, but they may be checking for certain web browsers and if they don't get it they close the connection.
I am not sure exactly why, but they may be checking for certain web browsers and if they don't get it they close the connection.
The API is intended for tool developers. In the documentation they recommend providing a unique User-Agent string so that they can potentially tailor a response (ie if the tool is in the wild and the API is updated, they might keep the old response format for a certain User-Agent string). However CCP being CCP and the EVE API being Garthagk's pet project (and Garthagk no longer being an employee of CCP...) it's entirely possible that not receiving a User-Agent string at all causes something to fail silently.
The point is if you just telnet to api.eve-online.com on port 80 and manually enter the GET query, the connection is terminated before the server sends anything... so the ASP process is dying (or being killed?) before it even gets the opportunity to generate an HTTP response code.
Ok, it turns out that the dead simple example given on the API website (using httplib instead of urllib2) uses HTTP/1.1 and sends the GET string, the (required) Host header and an Accept-encoding header.
The issue might be as simple as api.eve-online.com being a virtual site? Or IIS is configured to drop HTTP/1.0 and HTTP/0.9 connections.
Anyway, using telnet to api.eve-online.com on port 80 I verified that EVE API will respond to:
GET /<querystring> HTTP/1.1
Host: api.eve-online.com
So, we presume that LuaSocket either doesn't know about HTTP/1.1 or doesn't produce compliant messages (ie missing host header or the HTTP/1.1 tag).
Well I don't know about that. I used tcpdump to dump a session using LuaSocket between MUSHclient and my home web server (asking for the root document) and this is what it generated:
The only problem I can see here is the user-agent, so a custom query using some other agent may well get through.
GET / HTTP/1.1
host: 10.0.0.2
te: trailers
connection: close, TE
user-agent: LuaSocket 2.0.1
The only problem I can see here is the user-agent, so a custom query using some other agent may well get through.
... other than "Host" != "host". Sure.
fails.
So that's the problem there. LuaSocket isn't generating a Host header. (Which means it's technically not generating a HTTP/1.1 compliant request either. It is, instead, generating a bunch of garbage 'host', 'te' ... headers. And 'user-agent' != 'User-Agent' either.)
Nvm. It turns out that header field names are supposed to be case-insensitive. Which means that, since CCP is a MS shop, the fault probably lies with IIS.
GET /<query-string> HTTP/1.1
host: api.eve-online.com
So that's the problem there. LuaSocket isn't generating a Host header. (Which means it's technically not generating a HTTP/1.1 compliant request either. It is, instead, generating a bunch of garbage 'host', 'te' ... headers. And 'user-agent' != 'User-Agent' either.)
Nvm. It turns out that header field names are supposed to be case-insensitive. Which means that, since CCP is a MS shop, the fault probably lies with IIS.
Well I got it to work in the end, thanks to Isthiriel and my own debugging with Wireshark. :)
If you edit the file http.lua in the "socket" directory under the MUSHclient directory, you will find the spot where they use lower-case header names. Amend the table to capitalize them, and then the request works:
Edited to change User-agent to User-Agent.
If you edit the file http.lua in the "socket" directory under the MUSHclient directory, you will find the spot where they use lower-case header names. Amend the table to capitalize them, and then the request works:
local function adjustheaders(reqt)
-- default headers
local lower = {
["User-Agent"] = USERAGENT,
["Host"] = reqt.host,
["Connection"] = "close, TE",
["Te"] = "trailers"
}
-- if we have authentication information, pass it along
if reqt.user and reqt.password then
lower["Authorization"] =
"Basic " .. (mime.b64(reqt.user .. ":" .. reqt.password))
end
-- override with user headers
for i,v in base.pairs(reqt.headers or lower) do
lower[string.lower(i)] = v
end
return lower
end
Edited to change User-agent to User-Agent.
I agree with Isthiriel that they (Eve Online, not Luasocket) have incorrectly implemented the HTTP specification. From RFC 2616 section 4.2 we see:
At one stage I got this back from the Eve web site:
A more general solution would be to change (as well) the code I quoted above, where it has this part:
Even if you specify your own header, it is forced into lower case, which doesn't help. I initially tried to put a "Host" header into the user-supplied header table.
You would need to change string.lower(i) into a capitalization function. Such a function could be:
Each header field consists of a name followed by a colon (":") and the field value. Field names are case-insensitive.
At one stage I got this back from the Eve web site:
<h1>Bad Request (Invalid Header Name)</h1>
A more general solution would be to change (as well) the code I quoted above, where it has this part:
-- override with user headers
for i,v in base.pairs(reqt.headers or lower) do
lower[string.lower(i)] = v
end
Even if you specify your own header, it is forced into lower case, which doesn't help. I initially tried to put a "Host" header into the user-supplied header table.
You would need to change string.lower(i) into a capitalization function. Such a function could be:
function capitalize (s)
return string.upper (string.sub (s, 1, 1)) .. string.sub (s, 2)
end -- capitalize
Canonically, TE and User-Agent shouldn't be first-letter capital, rest lower either.
I've complained about CCP's code monkeys before (on their forums) but in this case I think it almost has to be IIS doing something wrong rather than the ASP written by CCP's web cell.
I've complained about CCP's code monkeys before (on their forums) but in this case I think it almost has to be IIS doing something wrong rather than the ASP written by CCP's web cell.
I think it is slightly annoying that Luasocket uses all lowercase. Although the spec says the case is irrelevant, most of the examples I have seen have had the words capitalized. For example:
http://en.wikipedia.org/wiki/HTTP
And you are right, they show (by example) both words capitalized, as in "Content-Length".
I think there are quite a few programmers that skip reading the specs, and code from examples, and thus they probably thought that a case-sensitive match was OK, and indeed was compatible with most browsers.
The utility Wireshark helped me in my debugging, see here:
http://www.wireshark.org/
This is a GPL utility (that is, free) that analyzes network traffic.
http://en.wikipedia.org/wiki/HTTP
And you are right, they show (by example) both words capitalized, as in "Content-Length".
I think there are quite a few programmers that skip reading the specs, and code from examples, and thus they probably thought that a case-sensitive match was OK, and indeed was compatible with most browsers.
The utility Wireshark helped me in my debugging, see here:
http://www.wireshark.org/
This is a GPL utility (that is, free) that analyzes network traffic.
so by changing the suggested portions you got luasocket to behave correctly? and are saying that even with it behaving correctly you still wouldn't get the expect items from CCP?
ok well you know I added the changes... thank you very much by the way... but i couldn't seem to get the information still so i figured it was just not gonna work... but then i tried to access the address again.. and got a loading problem page... so i guess it was just down and then just a moment ago i got what I was looking for so thank you. Now to move on the next step figuring out how to parse the xml... there any good books or reference manuals?
Well this is your lucky day because MUSHclient has a built-in XML parser (if you want to use it).
This test demonstrates how it can parse the XML into a Lua table:
Now you may not want to use MUSHclient to parse it, I think the Lua manual has an example of an XML parser as well.
This test demonstrates how it can parse the XML into a Lua table:
xml = [[
<?xml version='1.0' encoding='UTF-8'?>
<eveapi version="2">
<currentTime>2008-01-22 03:35:07</currentTime>
<result>
<characterID>1097517373</characterID>
<name>Nikolai Wolfwood</name>
<race>Caldari</race>
<bloodLine>Civire</bloodLine>
<gender>Male</gender>
<corporationName>Knights of Minas Tirith</corporationName>
<corporationID>1696815543</corporationID>
<balance>102059730.45</balance>
<attributeEnhancers>
<willpowerBonus>
<augmentatorName>Neural Boost - Basic</augmentatorName>
<augmentatorValue>3</augmentatorValue>
</willpowerBonus>
<memoryBonus>
<augmentatorName>Memory Augmentation - Basic</augmentatorName>
<augmentatorValue>3</augmentatorValue>
</memoryBonus>
<charismaBonus>
<augmentatorName>Social Adaptation Chip - Basic</augmentatorName>
<augmentatorValue>3</augmentatorValue>
</charismaBonus>
<perceptionBonus>
<augmentatorName>Ocular Filter - Basic</augmentatorName>
<augmentatorValue>3</augmentatorValue>
</perceptionBonus>
<intelligenceBonus>
<augmentatorName>Cybernetic Subprocessor - Basic</augmentatorName>
<augmentatorValue>3</augmentatorValue>
</intelligenceBonus>
</attributeEnhancers>
<attributes>
<intelligence>7</intelligence>
<memory>9</memory>
<charisma>6</charisma>
<perception>10</perception>
<willpower>7</willpower>
</attributes>
<rowset name="skills" key="typeID" columns="typeID,skillpoints,level,unpublished">
<row typeID="11584" skillpoints="12" level="0" />
<row typeID="3427" skillpoints="2829" level="2" />
<row typeID="3426" skillpoints="8016" level="3" />
<row typeID="3432" skillpoints="1581" level="1" />
<row typeID="3551" skillpoints="8000" level="3" />
<row typeID="3424" skillpoints="90510" level="4" />
<row typeID="3417" skillpoints="1415" level="2" />
<row typeID="3413" skillpoints="45255" level="4" />
<row typeID="21059" skillpoints="2829" level="2" />
<row typeID="3422" skillpoints="90510" level="4" />
<row typeID="3416" skillpoints="8000" level="3" />
<row typeID="3425" skillpoints="16000" level="3" />
<row typeID="3420" skillpoints="32000" level="3" />
<row typeID="3300" skillpoints="8000" level="3" />
<row typeID="3304" skillpoints="4243" level="2" />
<row typeID="3312" skillpoints="2829" level="2" />
<row typeID="3310" skillpoints="2829" level="2" />
<row typeID="3311" skillpoints="2829" level="2" />
<row typeID="3301" skillpoints="8000" level="3" />
<row typeID="3318" skillpoints="90510" level="4" />
<row typeID="3386" skillpoints="250" level="1" />
<row typeID="3377" skillpoints="45255" level="4" />
<row typeID="12385" skillpoints="77040" level="3" />
<row typeID="3378" skillpoints="45255" level="4" />
<row typeID="3375" skillpoints="45255" level="4" />
<row typeID="3374" skillpoints="45255" level="4" />
<row typeID="12376" skillpoints="24000" level="3" />
<row typeID="3379" skillpoints="41507" level="3" />
<row typeID="3392" skillpoints="45255" level="4" />
<row typeID="25863" skillpoints="750" level="1" />
<row typeID="3323" skillpoints="2829" level="2" />
<row typeID="12441" skillpoints="512000" level="5" />
<row typeID="3319" skillpoints="8000" level="3" />
<row typeID="3320" skillpoints="250" level="1" />
<row typeID="3321" skillpoints="500" level="1" />
<row typeID="3450" skillpoints="250" level="1" />
<row typeID="3449" skillpoints="250" level="1" />
<row typeID="3455" skillpoints="250" level="1" />
<row typeID="3411" skillpoints="750" level="1" />
<row typeID="3402" skillpoints="8000" level="3" />
<row typeID="3356" skillpoints="2829" level="2" />
<row typeID="3355" skillpoints="1415" level="2" />
<row typeID="12099" skillpoints="1500" level="1" />
<row typeID="3334" skillpoints="64435" level="3" />
<row typeID="3330" skillpoints="93019" level="4" />
<row typeID="3342" skillpoints="1000" level="1" />
<row typeID="12097" skillpoints="500" level="1" />
<row typeID="3327" skillpoints="45255" level="4" />
</rowset>
</result>
<cachedUntil>2008-01-22 04:35:07</cachedUntil>
</eveapi>
]]
t = assert (utils.xmlread (xml))
require "tprint"
tprint (t)
Now you may not want to use MUSHclient to parse it, I think the Lua manual has an example of an XML parser as well.