Network functions please...
Blitz3D Forums/Blitz3D Programming/Network functions please...
| ||
Would someone show me how to search for network games, so I can have an in-game list of available games instead of having to use the window StartNetGame() pops up. A few functions that see what connections a computer has - like the functions that tell blitz what graphics cards a computer has. Functions for looking through all the games currently available on the desired connection type - kinda like the ones for searching the graphics modes or files in a directory. That way, my game can just provide a list of possible games to join and let the user choose. And the player never has to type in anything but the name of the game he is creating. He doesn't have to watch as the cool graphics disappear and a stupid StartNetGame() window appears. The network is handled behind the scenes. Obviously, StartNetGame() uses some functions to get the information I want, but I can't find anything in blitz to get that information. Anybody have code or share my frustrations? |
| ||
There are 3 protocols you can use to write multiplayer games: directplay, tcp and udp. It seems you want to use directplay. I have no idea about that one. You maybe want to use the free version of BLitzPlay instead, a UDP library. There is also a version of the PHP script GNET for BlitzPlay (GNet see this page menu). GNET will host IPs etc. of running games on a webserver, exactly what you want. |
| ||
Yup, I've been down this lane. What you are looking for is a static server to keep all the information on available servers. Including IP's, Ping, COnnection Type, version, etc. etc. Sort of like what GameSpy Arcade is for major titles. Gnet is Blitz's miniscule version. It will save Game Names, Server Names, and IP's only. You then use the Include functions to get that data to your game. Gnet will work for you, unless your talking about needing to host a ton of servers. Like any major online game (Halo, AA, etc.) I use TCP and Gnet, if I had time or money, I would start my own site for hosting this info for games. Could make money to. |
| ||
I can't seem to find GNet anywhere. Can someone provide a link? [EDIT] Found GNet. Forgot the link like everyone else seems to have. Besides, what I'm looking for is LAN stuff, I'm not ready to make online games yet. GNet is a Blitz game server that allows blitz games to connect to a central online server (www.blitzbasic.com/gnet/gnet.php) so other players can join or host online games. I don't think I want to use GNet. It was a good suggestion though. Thanks for the effort. What I want to know is how StartNetGame() is obtaining a list of games, updating that list, and obtaining a list of possible connection types (TCP/IP, IPX, modem, serial, etc.). How does it get this infomation? Is it some DX thing? or is it part of windows? How does it get the information? Any more ideas out there? code, userlibs, something... DirectPlay is part of DX, but I don't care whether it's DX or windows or native blitz. Just show me how to do it in B3D and I'll be happy. I need something to tell my program all the known connection types (TCP/IP, IPX, etc). Then, once my program choses the connection type, something to list all games on that connection type WITHIN my program, however I want to display the list, NOT in that stupid StartNetGame() window. I do not want to have to type in an IP address every time I join a game, I want to be able to just choose a game and join. And I want this for a LAN not an online game. (yea, yea, I said the same thing over and over didn't I) |
| ||
What do you mean by "LAN" ? local ? or just Tcp/Ip ? if you want LAN game, you'll have to specify the Ip ... if you run locally with your fammily reseau, i d'ont know what will you call to receive informations. Unless you get datas from a server, and here, you'll have to get out from your local connection If you want to play with lan using Tcp and an other player on the web, you could have a database MySql you log and had a party/Ip/name of the party ... etc... It will be your server ! Then, just have to call the database to receive informations. Don't know if you use MySql, but it should be the best way ! |
| ||
You don't understand do you, Bobysait. LAN - Local Area Network TCP/IP - Transmission Control Protocol/Internet Protocol TCP/IP is the standard protocol for network and online connections. Other protocols exist, like IPX, which is outdated. It is NOT required to input an IP address, if you want proof, make a simple network program that inits using StartNetGame(). You will NEVER have to give ANY address information, no IP address, no computer name, no nothing, and yet you can still see all the games availiable on your network. I am on a network not connected to the internet. Besides, if I want a game between computer in my house, I don't want to send my game off to some server site just to get information that StartNetGame() gets without being online. Just play Warcraft III on you local network. Nowhere do you give it any IP information. You just click on the multiplayer button and it shows a list of all open games. I want to be able to do that kind of thing. I would like StartNetGame() to be broken into several function that don't have a stupid window. I don't know how or where StartNetGame() is getting the network information, but it is getting it and I want to know how. Maybe Mark has some hints... |
| ||
You need an enumeration routine...and there's just the function available in netapi32.dll. Here is the VB form: Private Declare Function NetServerEnum Lib "netapi32" _ (ByVal servername As Long, _ ByVal level As Long, _ buf As Any, _ ByVal prefmaxlen As Long, _ entriesread As Long, _ totalentries As Long, _ ByVal servertype As Long, _ ByVal domain As Long, _ resume_handle As Long) As Long if you want to see an example of this call in use, go to: http://vbnet.mvps.org/index.html?code/network/netserverenum.htm Hope this helps. Kevin |
| ||
Look promising...I'll post the Blitz code if it works... |
| ||
Here is an interesting site that has a free network library that you can use with Blitz3d. http://www.krylarskreations.com/knl.shtml Kevin |
| ||
Wow a livesign of Krylar! The Library looks good, tho: "You'll shave MONTHS off of your multiuser development cycle!" Well, not sure if my beard is really that large. :o) |
| ||
at LEAST months. I was checking out the library and it looks like just what Subirenihil was wanting. |
| ||
[EDIT] This what happens when you don't read the documentation and expect the demos to show everything! Read to the bottom of this to see how to connect without any IP stuff. Krylar looked great - until I tried to connect to the host. It needed me to input an IP address - exactly what I am trying to avoid. Like I keep saying, StartNetGame() is the only way I've found to avoid that, but it pops up a stinking window and when I'm running a fullscreen game the window is hidden, making it look like the game locked up (it doesn't lock up, its just waiting for StartNetGame(), which isn't going do anything until I exit the fullscreen so the user can see the StartNetGame() menu and choose something, which exiting fullscreen frees all my loaded images, so I have to reload them once I return to fullscreen, which is REALLY annoying. I'm working on that netapi32.dll stuff but I'm not doing something right. Anyone know how to do this with blitz? These are the things I have ported into blitz. Does anyone know about writing .decls? I have something wrong here, but I'm not sure whether it is in the .decls or in my code. Please debug. (Kevin8084, The net.bb is mostly the same your link went to ported to blitz. I ported the .decls came from there too. I've never ported anything before, so I'm sure its full of bugs) ----- netapi32.decls ----- .lib "netapi32.dll" NetServerEnum%(servername%, level%, buf%, prefmaxlen%, entriesread%, totalentries%, servertype%, domain%, resume_handle%):"NetServerEnum" NetApiBufferFree%(buffer%):"NetApiBufferFree" ----- net.bb ----- ;Windows Type used To call the Net API Const MAX_PREFERRED_LENGTH% = -1 Const NERR_SUCCESS% = 0 Const ERROR_MORE_DATA% = 234 Const SV_TYPE_WORKSTATION% = $1 Const SV_TYPE_SERVER% = $2 Const SV_TYPE_SQLSERVER% = $4 Const SV_TYPE_DOMAIN_CTRL% = $8 Const SV_TYPE_DOMAIN_BAKCTRL% = $10 Const SV_TYPE_TIME_SOURCE% = $20 Const SV_TYPE_AFP% = $40 Const SV_TYPE_NOVELL% = $80 Const SV_TYPE_DOMAIN_MEMBER% = $100 Const SV_TYPE_PRINTQ_SERVER% = $200 Const SV_TYPE_DIALIN_SERVER% = $400 Const SV_TYPE_XENIX_SERVER% = $800 Const SV_TYPE_SERVER_UNIX% = SV_TYPE_XENIX_SERVER Const SV_TYPE_NT% = $1000 Const SV_TYPE_WFW% = $2000 Const SV_TYPE_SERVER_MFPN% = $4000 Const SV_TYPE_SERVER_NT% = $8000 Const SV_TYPE_POTENTIAL_BROWSER% = $10000 Const SV_TYPE_BACKUP_BROWSER% = $20000 Const SV_TYPE_MASTER_BROWSER% = $40000 Const SV_TYPE_DOMAIN_MASTER% = $80000 Const SV_TYPE_SERVER_OSF% = $100000 Const SV_TYPE_SERVER_VMS% = $200000 Const SV_TYPE_WINDOWS% = $400000 ;Windows95 And above Const SV_TYPE_DFS% = $800000 ;Root of a DFS tree Const SV_TYPE_CLUSTER_NT% = $1000000 ;NT Cluster Const SV_TYPE_TERMINALSERVER% = $2000000 ;Terminal Server Const SV_TYPE_DCE% = $10000000;IBM DSS Const SV_TYPE_ALTERNATE_XPORT% = $20000000;rtn alternate transport Const SV_TYPE_LOCAL_LIST_ONLY% = $40000000;rtn Local only Const SV_TYPE_DOMAIN_ENUM% = $80000000 Const SV_TYPE_ALL% = $FFFFFFFF Const SV_PLATFORM_ID_OS2% = 400 Const SV_PLATFORM_ID_NT% = 500 ;Mask applied To svX_version_major in ;order To obtain the major version number. Const MAJOR_VERSION_MASK% = $F Type SERVER_INFO_100 Field sv100_platform_id% Field sv100_name% End Type ;Declare Function NetServerEnum Lib "netapi32" _ ; (ByVal servername As Long, _ ; ByVal level As Long, _ ; buf As Any, _ ; ByVal prefmaxlen As Long, _ ; entriesread As Long, _ ; totalentries As Long, _ ; ByVal servertype As Long, _ ; ByVal domain As Long, _ ; resume_handle As Long) As Long ;Declare Function NetApiBufferFree Lib "netapi32" _ ; (ByVal Buffer As Long) As Long ;Declare Sub CopyMemory Lib "kernel32" _ ; Alias "RtlMoveMemory" _ ; (pTo As Any, uFrom As Any, _ ; ByVal lSize As Long) ;Declare Function lstrlenW Lib "kernel32" _ ; (ByVal lpString As Long) As Long Global txt$ GetServers("") Print txt$ WaitKey End Function Form_Load() ; Command1.Caption = "Net Server Enum" End Function Function Command1_Click() ; Call GetServers("") End Function Function GetServers%(sDomain$) ;lists all servers of the specified Type ;that are visible in a domain. Local bufptr%=CreateBank(10024) Local dwEntriesread% Local dwTotalentries% Local dwResumehandle% Local se100.SERVER_INFO_100 Local success% Local nStructSize% Local cnt% nStructSize = 8;LenB(se100) ;Call passing MAX_PREFERRED_LENGTH To have the ;API allocate required memory For the Return values. ; ;The call is enumerating all machines on the ;network (SV_TYPE_ALL); however, by Or'ing ;specific bit masks For defined types you can ;customize the returned Data. For example, a ;value of 0x00000003 combines the bit masks For ;SV_TYPE_WORKSTATION (0x00000001) And ;SV_TYPE_SERVER (0x00000002). ; ;dwServerName must be Null. The level parameter ;(100 here) specifies the Data structure being ;used (in this Case a SERVER_INFO_100 structure). ; ;The domain member is passed as Null, indicating ;machines on the primary domain are To be retrieved. ;If you decide To use this member, pass ;StrPtr("domain name"), Not the String itself. success = NetServerEnum(0,100,bufptr,MAX_PREFERRED_LENGTH,dwEntriesread,dwTotalentries,SV_TYPE_ALL,0,dwResumehandle) ;If all goes well If success = NERR_SUCCESS And success <> ERROR_MORE_DATA Then ;loop through the returned Data, adding Each ;machine To the list For cnt = 0 To dwEntriesread - 1 ;get one chunk of Data And cast ;into an SERVER_INFO_100 struct ;in order To add the name To a list PokeInt bufptr, nStructSize * cnt,se100\sv100_platform_id PokeInt bufptr, nStructSize * cnt+4,se100\sv100_name Txt$=txt$+Chr$(13)+GetPointerToByteStringW(se100\sv100_name) Next End If ;clean up regardless of success NetApiBufferFree(bufptr) ;Return entries as sign of success Return dwEntriesread End Function Function GetPointerToByteStringW$(dwData%) Local tmp$="" Local tmplen% If dwData <> 0 Then tmplen = BankSize(dwData); * 2 If tmplen <> 0 Then For a=0 To tmplen-1 tmp$=tmp$+Chr$(PeekByte(dwdata,a)) Next End If End If Return tmp$ End Function |
| ||
Curious: did you want to create a bank that size? |
| ||
Here you have: Local se100.SERVER_INFO_100 Did you want se100.SERVER_INFO_100 = new SERVER_INFO_100? |
| ||
Actually, the bank size 10024 was a remnant of an attempt to get it to work. I originally had it 1024. I no longer need the se100. (the code above used to have it like you have it, but I changed it while attempting to fix the bug.) The new code runs without errors, but I have no idea why success returns 87. I don't think it runs properly yet because it can't find any games - even when I start one on the same computer - and only returns a success of 87. The msdn page says that the "level" parameter for NetServerEnum needs to be 100 or 101, but either of those values causes a "memory access violation". Suggestions anyone? Anybody know what & means on the end of VB numbers (ie 0&)? Bug finders, get to work! Here is my updated code, the .decls are the same: ;Windows Type used To call the Net API Const MAX_PREFERRED_LENGTH% = -1 Const NERR_SUCCESS% = 0 Const ERROR_MORE_DATA% = 234 Const SV_TYPE_WORKSTATION% = $1 Const SV_TYPE_SERVER% = $2 Const SV_TYPE_SQLSERVER% = $4 Const SV_TYPE_DOMAIN_CTRL% = $8 Const SV_TYPE_DOMAIN_BAKCTRL% = $10 Const SV_TYPE_TIME_SOURCE% = $20 Const SV_TYPE_AFP% = $40 Const SV_TYPE_NOVELL% = $80 Const SV_TYPE_DOMAIN_MEMBER% = $100 Const SV_TYPE_PRINTQ_SERVER% = $200 Const SV_TYPE_DIALIN_SERVER% = $400 Const SV_TYPE_XENIX_SERVER% = $800 Const SV_TYPE_SERVER_UNIX% = SV_TYPE_XENIX_SERVER Const SV_TYPE_NT% = $1000 Const SV_TYPE_WFW% = $2000 Const SV_TYPE_SERVER_MFPN% = $4000 Const SV_TYPE_SERVER_NT% = $8000 Const SV_TYPE_POTENTIAL_BROWSER% = $10000 Const SV_TYPE_BACKUP_BROWSER% = $20000 Const SV_TYPE_MASTER_BROWSER% = $40000 Const SV_TYPE_DOMAIN_MASTER% = $80000 Const SV_TYPE_SERVER_OSF% = $100000 Const SV_TYPE_SERVER_VMS% = $200000 Const SV_TYPE_WINDOWS% = $400000 ;Windows95 And above Const SV_TYPE_DFS% = $800000 ;Root of a DFS tree Const SV_TYPE_CLUSTER_NT% = $1000000 ;NT Cluster Const SV_TYPE_TERMINALSERVER% = $2000000 ;Terminal Server Const SV_TYPE_DCE% = $10000000;IBM DSS Const SV_TYPE_ALTERNATE_XPORT% = $20000000;rtn alternate transport Const SV_TYPE_LOCAL_LIST_ONLY% = $40000000;rtn Local only Const SV_TYPE_DOMAIN_ENUM% = $80000000 Const SV_TYPE_ALL% = $FFFFFFFF Const SV_PLATFORM_ID_OS2% = 400 Const SV_PLATFORM_ID_NT% = 500 ;Mask applied To svX_version_major in ;order To obtain the major version number. Const MAJOR_VERSION_MASK% = $F Type SERVER_INFO_100 Field sv100_platform_id% Field sv100_name% End Type ;Declare Function NetServerEnum Lib "netapi32" _ ; (ByVal servername As Long, _ ; ByVal level As Long, _ ; buf As Any, _ ; ByVal prefmaxlen As Long, _ ; entriesread As Long, _ ; totalentries As Long, _ ; ByVal servertype As Long, _ ; ByVal domain As Long, _ ; resume_handle As Long) As Long ;Declare Function NetApiBufferFree Lib "netapi32" _ ; (ByVal Buffer As Long) As Long ;Declare Sub CopyMemory Lib "kernel32" _ ; Alias "RtlMoveMemory" _ ; (pTo As Any, uFrom As Any, _ ; ByVal lSize As Long) ;Declare Function lstrlenW Lib "kernel32" _ ; (ByVal lpString As Long) As Long Global txt$ Print GetServers("") Print txt$ WaitKey End Function Form_Load() ; Command1.Caption = "Net Server Enum" End Function Function Command1_Click() ; Call GetServers("") End Function Function GetServers%(sDomain$) ;lists all servers of the specified Type ;that are visible in a domain. Local bufptr%;=CreateBank(10024) Local dwEntriesread% Local dwTotalentries% Local dwResumehandle% Local se100.SERVER_INFO_100=New SERVER_INFO_100 Local success% Local nStructSize% Local cnt% nStructSize = 8;LenB(se100) Local d1=CreateBank(8) d2=CreateBank(Len(sdomain$)) For a=0 To Len(sdomain$)-1:PokeByte d2,a,Asc(Mid$(sdomain$,a+1,1)):Next ;Call passing MAX_PREFERRED_LENGTH To have the ;API allocate required memory For the Return values. ; ;The call is enumerating all machines on the ;network (SV_TYPE_ALL); however, by Or'ing ;specific bit masks For defined types you can ;customize the returned Data. For example, a ;value of 0x00000003 combines the bit masks For ;SV_TYPE_WORKSTATION (0x00000001) And ;SV_TYPE_SERVER (0x00000002). ; ;dwServerName must be Null. The level parameter ;(100 here) specifies the Data structure being ;used (in this Case a SERVER_INFO_100 structure). ; ;The domain member is passed as Null, indicating ;machines on the primary domain are To be retrieved. ;If you decide To use this member, pass ;StrPtr("domain name"), Not the String itself. success = NetServerEnum(0,d1,bufptr,MAX_PREFERRED_LENGTH,dwEntriesread,dwTotalentries,SV_TYPE_ALL,d2,dwResumehandle) ;If all goes well If ((success = NERR_SUCCESS) And (success <> ERROR_MORE_DATA)) Then ;loop through the returned Data, adding Each ;machine To the list For cnt = 0 To dwEntriesread - 1 ;get one chunk of Data And cast ;into an SERVER_INFO_100 struct ;in order To add the name To a list PokeInt bufptr, nStructSize * cnt,PeekInt(d1,0);se100\sv100_platform_id PokeInt bufptr, nStructSize * cnt+4,PeekInt(d1,4);se100\sv100_name Txt$=txt$+Chr$(13)+GetPointerToByteStringW(PeekInt(d1,4));se100\sv100_name) Next End If ;clean up regardless of success NetApiBufferFree(bufptr) ;Return entries as sign of success Return dwEntriesread ;change this to "Return success" if you want to see what success returns End Function Function GetPointerToByteStringW$(dwData%) Local tmp$="" Local tmplen% If dwData <> 0 Then tmplen = BankSize(dwData); * 2 If tmplen <> 0 Then For a=0 To tmplen-1 tmp$=tmp$+Chr$(PeekByte(dwdata,a)) Next End If End If Return tmp$ End Function |
| ||
Error code 87 = invalid parameter |
| ||
Thanks kevin. That way I at least know why it doesn't return any servers. |
| ||
no problem. Good luck on your coding! |
| ||
How do I send it a pointer to an array of the SERVER_INFO_100 structure? Or shouldn't a bank work just fine? The first two parameters need to be 0, 100. The remaining parameters still need to be debugged. |
| ||
I just ran your code and got an error 124 (invalid level error) |
| ||
An array is, itself, a pointer to the data type that the array holds, yes? I don't think that it's needed to do more than send it the array. |
| ||
Yea, it did that to me once with the first code. It always gives me an 87 with the second code. I'm tweeking the variables and the buf parameter. I'm always getting a "memory access violation" and crashing blitzcc. I'm so glad Mark separated the compiler from the editor:) |
| ||
For error lookups, go here: http://www.allapi.net/php/errlookup/errlookup.php Very handy site! |
| ||
I'll try that then. |
| ||
You're in Montana, yes? Chess player? |
| ||
Thanks for the error page. Identifier "se100" may not be used this way. Dim se100.SERVER_INFO_100(100);=New SERVER_INFO_100 success = NetServerEnum(0,100,se100,MAX_PREFERRED_LENGTH,dwEntriesread,dwTotalentries,SV_TYPE_ALL,0,dwResumehandle) |
| ||
no problem...I'm glad that sites such as that exist! |
| ||
Belgrade, MT How'd you know I liked chess? |
| ||
you ranked #6 in 2003 tournament. You were in 8th grade at the time :) |
| ||
The identifier error is in the success line. |
| ||
I think that you're going to get your code working today. |
| ||
There were two chess tournaments i entered in 2003 (those were the only tournaments I have ever entered, more recent ones have coincided with other more important events in my life so I haven't gotten a chance to enter) one on May 3, the other was on September 27. I think I got 4rth in May, just 'cause I was nervous and let a little kid pull a seven move checkmate on me:( My little brother took first in the level beneath me. I had moved up into the next level as had all the other good chess players. My best friend won first. |
| ||
What place did you get in the tournament? |
| ||
In May, Ben Darling took 1st place. Is this your best friend? The kid pulled the 7 move checkmate on you in Round 3, yes? |
| ||
I didn't play. I haven't played chess in years (though I started when I was four years old LOL) |
| ||
No, I didn't play Ben Darling in May. Some little 5th grader (that was the 7 move checkmate) was the only person I lost to that day. In September, Nathan Clevidence won. I think he won in May too, but he was in the 9th-12th range. Nathan is my best friend, haven't met Ben much other than at the chess tournaments. |
| ||
Sorry about looking into your life a little. If you are curious, do a google search for "kevin8084" and for "klee8084". These are both me. You might find the reverse engineering aspects worthwhile. Now, gotta go for a while. Later! |
| ||
(The 5th grader pulled the 7 move checkmate on me in round 1) Back to topic. How do you send an array to a function? |
| ||
Just call the array inside of the function:Dim a(10) For x=0 To 9 a(x)=x Next doit() WaitKey() End Function doit() For x=0 To 9 Print a(x) Next End Function Or, if you are worried about the scope, you can do this: Global a[10] For x=0 To 9 a[x]=x Next doit() WaitKey() End Function doit() For x=0 To 9 Print a[x] Next End Function |
| ||
Um, I don't see how that works for the code. If you find something that works, please tell me. |
| ||
I just noticed that I need pointers (aka. banks) for some of the parameters instead of actual values. Success=0 (which is NERR_SUCCESS, which is exactly what you want to see). Everything seems to run great - UNTIL the program executes the End command, which causes a "Memory access violation" Here's the new code (I have remove most of the commented code to make this a smaller post): ;Windows Type used To call the Net API Const MAX_PREFERRED_LENGTH% = -1 Const NERR_SUCCESS% = 0 Const ERROR_MORE_DATA% = 234 Const SV_TYPE_WORKSTATION% = $1 Const SV_TYPE_SERVER% = $2 Const SV_TYPE_SQLSERVER% = $4 Const SV_TYPE_DOMAIN_CTRL% = $8 Const SV_TYPE_DOMAIN_BAKCTRL% = $10 Const SV_TYPE_TIME_SOURCE% = $20 Const SV_TYPE_AFP% = $40 Const SV_TYPE_NOVELL% = $80 Const SV_TYPE_DOMAIN_MEMBER% = $100 Const SV_TYPE_PRINTQ_SERVER% = $200 Const SV_TYPE_DIALIN_SERVER% = $400 Const SV_TYPE_XENIX_SERVER% = $800 Const SV_TYPE_SERVER_UNIX% = SV_TYPE_XENIX_SERVER Const SV_TYPE_NT% = $1000 Const SV_TYPE_WFW% = $2000 Const SV_TYPE_SERVER_MFPN% = $4000 Const SV_TYPE_SERVER_NT% = $8000 Const SV_TYPE_POTENTIAL_BROWSER% = $10000 Const SV_TYPE_BACKUP_BROWSER% = $20000 Const SV_TYPE_MASTER_BROWSER% = $40000 Const SV_TYPE_DOMAIN_MASTER% = $80000 Const SV_TYPE_SERVER_OSF% = $100000 Const SV_TYPE_SERVER_VMS% = $200000 Const SV_TYPE_WINDOWS% = $400000 ;Windows95 And above Const SV_TYPE_DFS% = $800000 ;Root of a DFS tree Const SV_TYPE_CLUSTER_NT% = $1000000 ;NT Cluster Const SV_TYPE_TERMINALSERVER% = $2000000 ;Terminal Server Const SV_TYPE_DCE% = $10000000;IBM DSS Const SV_TYPE_ALTERNATE_XPORT% = $20000000;rtn alternate transport Const SV_TYPE_LOCAL_LIST_ONLY% = $40000000;rtn Local only Const SV_TYPE_DOMAIN_ENUM% = $80000000 Const SV_TYPE_ALL% = $FFFFFFFF Const SV_PLATFORM_ID_OS2% = 400 Const SV_PLATFORM_ID_NT% = 500 Const MAJOR_VERSION_MASK% = $F Type SERVER_INFO_100 Field sv100_platform_id% Field sv100_name% End Type Global txt$ Print GetServers("") Print txt$ WaitKey End Function GetServers%(sDomain$) Local bufptr%=CreateBank(1024) Local dwEntriesread%=CreateBank(4) Local dwTotalentries%=CreateBank(4) Local dwResumehandle% Local success% Local nStructSize% Local cnt% nStructSize = 8;LenB(se100) Local d1=CreateBank(1024) d2=CreateBank(Len(sdomain$)) For a=0 To Len(sdomain$)-1:PokeByte d2,a,Asc(Mid$(sdomain$,a+1,1)):Next success = NetServerEnum(0,100,bufptr,MAX_PREFERRED_LENGTH,dwEntriesread,dwTotalentries,SV_TYPE_ALL,0,dwResumehandle) If ((success = NERR_SUCCESS) And (success <> ERROR_MORE_DATA)) Then For cnt = 0 To PeekInt(dwEntriesread,0) - 1 Txt$=txt$+Chr$(13)+GetPointerToByteStringW(PeekInt(bufptr,cnt*nStructSize+4));se100\sv100_name) Next End If NetApiBufferFree(bufptr) Return PeekInt(dwEntriesread,0) End Function Function GetPointerToByteStringW$(dwData%) Local tmp$="" Local tmplen% If dwData <> 0 Then tmplen = BankSize(dwData); * 2 If tmplen <> 0 Then For a=0 To tmplen-1 tmp$=tmp$+Chr$(PeekByte(dwdata,a)) Next End If End If Return tmp$ End Function |
| ||
This little example shows how to set up an array of types and shows that functions can access the array without being explicitly passed a pointer:Type mytype Field x#,y#,z# End Type Dim cool.mytype(10) doit() WaitKey() End Function doit() cool.mytype(0)=New mytype cool(0)\x=5 Print cool(0)\x delete cool(0) End Function Ahh...I see that you posted in the interim |
| ||
Thanks for the code, but that's not quite what I had in mind. I was wanting to send the array of types out to the NetServerEnum - and it didn't like it. Anyway, I figured out that my idea of using a bank was fine, the problem was that dwEntriesRead and dwTotalEntries needed to be banks too. But there's still a problem with my code? The End statement causes a "Memory access violation" |
| ||
I have to go offline for a bit. I will attempt to recreate your program from scratch and see if I come up with the same error...I'll post when the program is complete. Kevin |
| ||
So far I'm having the same luck as you...very frustrating |
| ||
The NetServerEnum seems to be messing up the bank, so when Blitz tries to free it it causes an error. Insert "FreeBank bufptr" anywhere after you create the bank. FreeBank will cause an error if you insert it after the NetServerEnum. If you insert it before the NetServerEnum, then End causes an error (because End cleans up everything, including freeing existing banks) I think it NetServerEnum may be using the wrong variable initialization command - I saw something somewhere about you must use a certain command for declaring variables when creating a dll. I will look at finding the windows command to create a bank that I can send to NetServerEnum. This is looking very promising, but the task is a little more than I expected. I hope we can get this working so that future programmers can have a more professional style networking lib at their fingertips - and our names possibly in the credits. Thanks for all your help Kevin. It has been a pleasure knowing someone that I can work with. |
| ||
GRRRrrrrrr... I think I need someone to write a dll to do this. I'd try, but I don't have anything but Blitz. This is a hint... |
| ||
Microsoft gives out it's express edition for free. You can make dlls quite easily with the Visual C++ Express edition or Visual C# express edition. |
| ||
Where do I get it at (I could search but why bother when you could tell me)? [EDIT] Here's the download link if anybody else is curious: Express C++ |
| ||
You can also get the Visual Basic express edition and the Visual J# express edition. Needless to say, I have them all :) |
| ||
In your code you can stop the error messages by: While success=$234 success = NetServerEnum(0,100,bufptr,MAX_PREFERRED_LENGTH,dwEntriesread,dwTotalentries,SV_TYPE_ALL,0,dwResumehandle) Wend Simply continuing on receiving data from the function while there is still information. |
| ||
Oooooooooooooh! ERROR_MORE_DATA is supposed to be $234, not 234. Thanks Kevin! Now, to see if I can start a server. |
| ||
no problem |
| ||
Hey Kevin! I found out why adding those lines prevents the error. It SKIPS "success=NetServerEnum(0,100,..." for proof, insert a "Stop" inside the loop - the "Stop" will never get triggered. I think you wanted to do something like this: success=$234 While success=$234 success=NetServerEnum(0,100,bufptr,MAX_PREFERED_LENGTH,dwEntriesread,dwTotalentries,SV_TYPE_ALL,0,dwResumehandle) Wend Or like this: Repeat success=NetServerEnum(0,100,bufptr,MAX_PREFERED_LENGTH,dwEntriesread,dwTotalentries,SV_TYPE_ALL,0,dwResumehandle) Until success=$234 BUT I FOUND I WAS WRONG ABOUT KNL!!! I got it to work! I'm on a different computer from my programming one so I can't post the code right now - I'll post as so as I can. Thanks for all your help Kevin! You're definently going to be in the credits. I could try to send you a copy of of the game if you like - if/when I finish it. Thanks! |
| ||
Glad to have helped, Subirenihil :) |
| ||
Alright! I now have a program to demonstrate a no-IP network connection. Step 1: Download and install the K-NetLib K-NetLib Step 2: Run this code on several computers on your network. (it's quite elaborate, but uncommented) |