• Welcome to Valhalla Legends Archive.
 

SCGP Client (VB6 Open Source)

Started by Ringo, November 03, 2008, 08:20 AM

Previous topic - Next topic
|

Ringo

umm, yeah. After posting that SC mini map code, and a few pms i got, I figgerd ppl were interested in this. So I started writeing an open source client over the weekend (been a long weekend :()
Lately ive been writeing a SCGP class, one thats copy/paste friendly that can be added to any vb project, and work -- some kind of base to modify, depending what i feel like doing on the day.
The class is only about 20% finished -- but it can host games, join games, download and upload maps, chat with players -- pretty much everything game room related.
See below for infomation about SCGP class, how to use it, and the event's it returns.

As for this open source client, you can download it here: SCGP.zip
If you're wundering what it is, heres a few screen shots of it:

Ive also included an executable, so even if you don't have VB, you can play around with it.
Given the time I found to write it, the code is pretty messy and some of my home made control class's are.. well, in a word.. shit. However, it should be a good example, which is all I really had in mind (Just went abit OTT, you know.. as you do) :(
Anyway, Enjoy!



As for the SCGP class:
You can view it here: clsSCGP.cls
It requires you have a version of storm.dll in the project directory. I Find storm.dll version 1.0.9.0 to be most stable.
1st of all, you MUST *update* the class, every 250ms, other wise it will be about as active as a 20 stone woman in bed.
So basicly, just have a timer with an interval of 250ms, and in the timer() sub, call the SCGP.update sub.
This will allow it to track time (even tho, that is at best, very basic at the moment)
You MUST also pass UDP data to the class via SCGP.OnData(Data, IP, Port)


Now, lets say you want to join a game:
You need to pass the class a few things to get the ball rolling.
You need the following infomation:

lngIP = inet_addr("0.0.0.0")
intPort = htons(6112)
MyAcc = "Ringo"
MyStats = "PXES 0 0 0 0 0 0 0 0 PXES"
Password = ""
Handle = sckUDP.SocketHandle

Call SCGP.InitJoin(lngIP, intPort, MyAcc, MyStats, Password, Handle)


As for creating a game, you need abit more infomation for this.

Handle = sckUDP.SocketHandle
MPQ = app.path & "\(8)Big Game Hunters.scm"
intGameType = &HF 'top vs bottom
intPenalty = 1 '7v1
MPQHash = GetFileTimeHash(MPQ) 'get the hash from the file time or w/e u put it
lngStatsCode = &H0 'melee stats
lngMyClient = &H53455850 'PXES
MyAcc = "Ringo"
GameName = "Lets Stomp Comps"
GamePass = ""
GameSpeed = 6
GameStats = SCGP.GetMapStats(MPQ, GameSpeed, intGameType, intPenalty, MyAcc)

If (SCGP.InitCreate(Handle, MPQ, intGameType, intPenalty, MPQHash, lngStatsCode, lngMyClient, MyAcc, GameName, GamePass, GameStats)=false then
    'handle any error here
end if

Notice I got the game stats string from SCGP.GetMapStats()
The class also has a few handy functions for reading map files.


Public Function GetMapIcon(ByVal strMPQ As String) As Long

This function will accept a path to a map file, and return what type of icon the map has.
For example, 0 = none, 1 = blizzard, 2 = ladder, etc


Public Function GetMapInfo(ByVal strMPQ As String, _
                           ByRef lngWidth As Long, _
                           ByRef lngHeight As Long, _
                           ByRef bIcon As Byte, _
                           ByRef bTitle As Byte, _
                           ByRef bPlayers As Byte, _
                           ByRef bComputers As Byte, _
                           ByRef strTitle As String, _
                           ByRef strDesc As String) As Boolean

This function takes a path to a map file, and returns its width, height, icon, titleset, number of human players, number of computer players, the map name (not file name) and the map description.
Pretty much all the infomation you need, when you click a map on starcraft, and view its info when creating a game.
also, VERY IMPORTANT, is the number of players and computers returned.
You need this number, to derive the correct penalty index (as explained under GetMapStats) for mostly, tvb games.


Public Function GetMapStats(ByVal strMPQ As String, _
                            ByVal bSpeed As Byte, _
                            ByVal intType As Integer, _
                            ByVal bPenalty As Byte, _
                            ByVal strHost As String) As String

This function takes a path to a map file, a game speed, a game type, a penalty for said game type, and your account name, and returns a map stats string.
You need this map stats string when calling the SCGP.InitCreate(), you also need this for sending 0x1C to battle.net, to create the game.
Its very important, you pass the correct penalty value.
for example, it must never be below 1, and never above 7.
In a team game, like team melee, team ffa etc, 1=2teams, 2=3teams, 3=4teams.
For top vs bottom, penalty = the number of players in the away team.
You need the max number of players (Players+Comps, from the GetMapInfo) to get a true list of top vs bottom penaltys.
Top vs bottom penaltys, basicly goes like this:
1 = 7v1
2 = 6v2
3 = 5v3
etc etc etc
but for a map with less than 8 players, it goes somthing like
1 = 5v1
2 = 4v2
3 = 3v3
4 = 4v2
etc.
So, its important you pass the correct penalty.
Why is it important?
Because when hosting, joining players will use the game stats string to derive the team infomation, max number of players, etc etc.
Not to mention, I flip the penalty valur around, in the getmapstats function, and the initcreate sub, so that I can just pass it the combo box index.
Makes it simpler on the out side, to list the teams/penaltys the same way starcraft does, and just pass the listindex value to the functions.
(Well, ok, not so important)



Public ReadMPQFile(ByVal strMPQ As String, ByVal strFile As String, ByRef strBuffer As String) As Boolean

This function, takes a path to a MPQ file, the name of a file with in the mpq, and returns the file data in strBuffer.
The function returns false, if it fails.







Now for a list of the current supported events:

Public Event OnJoinLatency()

Speaks for its self -- this is raised after about 8 seconds of joining the game, if the host doesnt respond.


Public Event OnCreate(ByVal strMAP As String)
    strMAP = path to the map file

This is raised 1st, when you create agame, followed by all the other events


Public Event OnEnterRoom()

This is raised when you have enterd the game room.
Normaly, this is the 1st event you get after joining agame, letting you know you're in.
Its also raised if your hosting agame, following the OnCreate() event.



Public Event OnJoinReject(ByVal bReassion As Byte)
    Select Case bReassion
        Case &H0:   "You Have Been Booted.")
        Case &H1:   "You Have Been Banned.")
        Case &H2:   "Game Creater Has Closed All Avalible Slots.")
        Case &H3:   "Game Host Has Left The Game.")
        Case &H4:   "Unable To Join The Game.")
        Case &H5:   "Save Game File Not Found.")
        Case &H6:   "Unable To Write Scenario File.")
        Case &H7:   "Invalid Game Version.")
        Case &H8:   "Invalid Spawn Version.")
        Case &H9:   "Unable To Authenticate Map.")
    End Select

Pretty much speaks for its self there.
Note: this event will be raised, with the reassion 0x04, if the host rejects you'r joing request.



Public Event OnMapStats(ByVal strGameName As String, _
                        ByVal strGamePass As String, _
                        ByVal strGameStats As String, _
                        ByVal intGameType As Integer, _
                        ByVal intPenaltyA As Integer, _
                        ByVal lngPenaltyB As Long, _
                        ByVal lngMaxPlayers As Long, _
                        ByVal intMapWidth As Integer, _
                        ByVal intMapHeight As Integer, _
                        ByVal strSlotSelect As String, _
                        ByVal strRaceSelect As String)

Thses values pretty much speak for them selfs.
The penaltyA value, is the basic penalty index.
The penaltyB, is the value that goes with the penalty index -- like the time in a slaughter game.
strSlotSelect and strRaceSelect are both 12 bytes long. They contain the base stats of each player/game slot. so for example, if the 3rd byte in slotselect is not 0x06, you can not change game room slot 3's state (if you are the host)
if the 4th byte of raceselect is not 0x06, then the 3rd game room slot can not have its race changed.
Kind of like, comps in UMS games, and fixed races in UMS game.



Public Event OnForceName(ByVal strForceA As String, _
ByVal strForceB As String, _
ByVal strForceC As String, _
ByVal strForceD As String)

Raised to tell you the force names, mainly, in UMS games.
For example, the team names in a UMS game.



Public Event OnCheckMap(ByVal lngLengh As Long, _
ByVal lngChecksum As Long, _
ByVal strMapName As String, _
ByRef bGotIt As Boolean, _
ByRef strMapData As String)

Raised when the class wants to know if you need to download the map or not.
The lengh is the lengh of the map file.
the checksum is a checksum of the file -- I just store that in the maps file time.
if you have the map already and dont need to download it, you must set the bGotIt to true, and fill strMapData with the file data, so the class can then send the map to any other players who may need it.



Public Event OnMapDownloaded(ByVal lngLengh As Long, _
     ByVal lngChecksum As Long, _
     ByVal strMapName As String, _
         ByRef strData As String)

Simply telling you, the class has finished downloading the map.
Lengh of the map, checksum of the map, name of the map, map file data.



Public Event OnMapDownloading(ByVal bPercent As Byte, ByVal bSlot As Byte)

tells you that a player in the game room slot, has updated their download percentage.
This is also raised for you're own download progress, as well as any other.



Public Event OnSlotUpdate(ByVal bSlot As Byte, _
  ByVal strAccount As String, _
      ByVal bState As Byte, _
  ByVal enRace As SCGP_RACE, _
  ByVal bTeam As Byte, _
  ByVal lngPing As Long, _
  ByVal bDLPer As Byte)

Raised when a game slot is updated. Explains its self pretty well there.



Public Event OnChat(ByVal strAccount As String, ByVal strChat As String)




Public Event OnSlotPing(ByVal bSlot As Byte, ByVal lngPing As Long)

Raised when a player in the given game room slot, has got a ping update.



Public Event OnPlayerJoin(ByVal strAccount As String, ByVal strStats As String)

Raised when a player joins the game.
This does not include existing players already in the game.



Public Event OnPlayerQuit(ByVal bSlot As Byte)

Raised when a player in a given game room slot, has quit the game.



Public Event OnGameStart()

Explains its self pretty well.
This is also when the road ends.
You should beable to just about idle ingame with 1 or more players, but this class really stops when it comes to game start.
As siad above, its currently only around 20% compleat.








Game room functions:

Public Sub Clear()

Does exacly what it says, clears the class and renders it "offline".



Public Sub Quit()

Tells everyone in the game u have quit.
This does not call the .clear sub, you must do that you're self if you also want to reset the class.



Public Sub Chat(ByVal strChat As String)

Wanna talk to ppl?



Public Sub ChangeRace(ByVal bSlot As Byte, ByVal enRace As SCGP_RACE)

Wanna change you're race, or the race of another player etc?
if your changing your own race, the slot must be 0x08.


Public Sub ChangeTeam(ByVal bTeam As Byte)

Wanna move to another team, or to a new slot in your current team?



Public Sub MovePlayerTeam(ByVal bSlot As Byte, ByVal bTeam As Byte)

Are you the host, and you want to move somone to another team?
You can not move you're self.
This is for TvB game type only.



Public Sub MovePlayerSlot(ByVal bSlot As Byte, ByVal bToSlot As Byte)

Same as moveplayerteam iirc, but you can be abit more selective with what slot you move them to.
Same rules apply as MovePlayerTeam



Public Sub ChangeSlotState(ByVal bSlot As Byte, ByVal bState As Byte)

If your the host, and you want to change the state of a slot, use this.
If you change the state of a slot that contains a player, it will boot them automaticly.
0x05 = computer
0x06 = open
0x08 = closed


Public Sub BootPlayer(ByVal strAccount As String, Optional ByVal bBan As Boolean = False)

Boot or ban a player from the game.






And thats about it, THX GOD, lawl.
what a long ass post ><
I feel like i'm even talking to my self in this post.
Hope you enjoy it, add to it, gib feed backs and take the piss or w/e floats ur boat.
Peace!

Sixen

#1
Very nice, Ringo!
Blizzard Tech Support/Op W@R - FallenArms
The Chat Gem Lives!
http://www.diablofans.com
http://www.sixen.org

Yegg


vector

Oh my freaking gosh, Ringo. Blizzard could use your skills, hehe. This is really nice. I mean, the concept of creating a starcraft client is way beyond me.

MysT_DooM



vb6, something about that combination of numbers and letters is sexy

Ringo

Quote from: vector on November 03, 2008, 03:13 PM
Oh my freaking gosh, Ringo. Blizzard could use your skills, hehe. This is really nice. I mean, the concept of creating a starcraft client is way beyond me.
lol, I will take that as sarcasm :p
I don't have any skillz :D

Aside, did you guys download the source and try it?
I had a few problems orginaly compileing it, vb compiler was having as hissy fit about module.variable = X, but calmed down with variable = X

Quote from: MysT_DooM on November 03, 2008, 05:18 PM
sob
Hi MysT :)
Sob = you're sobbing? :( why? SC2 is out soon, BW is pretty lifeless and this SCGP class should be a good referance for the map promotor you have been working on for ages :)
or, Sob = son of bitch? :P yeah my moms a bitch!

MysT_DooM

son of a bitch!
sigh...ur right it is helpful for my map promoter prog.  Ill take a look at the class this weekend. 
The farthest I got in this sc udp was joining the game and seeing people chat.  Although they couldn;t see me in the room.  So my sort of fustration was like...damn...he posted all the answers...but its cool...itll help other people im sure more than the incomplete stuff i posted.  But yeh SC2 is coming so might as well put out all the SC stuff.


vb6, something about that combination of numbers and letters is sexy

Racial


Ringo

This should all be fun and working again now, since sc/bw 1.16a patch just went live, plus warden is now off :p
Idk if any of SCGP has changed tho -- probly not.

Ringo

#9
Ive just spent the past hour updating this bot!
It now supports 1.16a warden -- by that I mean, basic checking/downloading of module's, preping them, loading them, initializeing them and calling a select few functions to handle 0x05. All 0x02 stuff is done manualy.
Besides that, the only new addition is a zlib.dll -- I did all the ASM stuff manualy (yeah, my VB6 ASM class, is ugly, but it works none the less :P)
Remember, this is for educational useage alone, so I don't want to see any morons trying to help load bot kiddies to add it to *their* bot's, If I do, I won't be doing this stuff again. (goes with out saying really)
How ever, Ive wrote the modWARDEN.bas iin such away, it should be pretty hard to modify and put into a load bot, or alike -- unless you know what you're doing.
Besides that, the 10mins I was online with it, testing, it looked like SCGP hasn't changed at all in 1.16.
Hope you enjoy it.
SCGP.zip

Sixen

Once again, Ringo pulls through, =).

Interesting stuff man..
Blizzard Tech Support/Op W@R - FallenArms
The Chat Gem Lives!
http://www.diablofans.com
http://www.sixen.org

MyndFyre

Quote from: Ringo on December 15, 2008, 09:33 AM
How ever, Ive wrote the modWARDEN.bas iin such away, it should be pretty hard to modify and put into a load bot, or alike -- unless you know what you're doing.
Sadly it's a really difficult line to walk.  I think a lot of us don't want to see this kind of abuse.....  I don't understand what purpose it serves.

Nice work.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

Barabajagal

#12
I'm sorry, I just had to laugh out loud when I saw this:
    Select Case A
        Case &H10000021
        Case &H10000050
        Case &H10000070
        Case &H100000A1
        Case &H11000020
        Case &H11000021
        Case &H16000030
        Case &H1700007C
        Case &H170001E9
        Case &H19000059
        Case &H1A0000C3
        Case &H1F000219
        Case &H1F000234
        Case &H20000022
        Case &H20000049
        Case &H23000048
        Case &H24000032
        Case &H250001EE
        Case &H250001FE
        Case &H28000091
        Case &H2A0000E1
        Case &H2A0000F1
        Case &H3000069C
        Case &H300006D4
        Case &H300006D7
        Case &H300007A8
        Case &H32000121
        Case &H3700008E
        Case &H40000081
        Case &H58000092
        Case &HC0002D0
        Case &HD0000E8
        Case &HE0001FD
        Case &HE000622
        Case Else: Exit Function
    End Select

You know you can do "Case &H10000021, &H10000050, etc...", right? Hopefully it's more efficient than running 35 case checks, too...

Edit: Also, I tried logging in, and noticed something I find quite funny. The icon for my account (RealityRipple) on Warcraft 2, has the #1 IronMan icon next to it, even though I'm #33.

brew

Quote from: Andy on December 15, 2008, 04:48 PM
I'm sorry, I just had to laugh out loud when I saw this:
    Select Case A
        Case &H10000021
        Case &H10000050
        Case &H10000070
        Case &H100000A1
        Case &H11000020
        Case &H11000021
        Case &H16000030
        Case &H1700007C
        Case &H170001E9
        Case &H19000059
        Case &H1A0000C3
        Case &H1F000219
        Case &H1F000234
        Case &H20000022
        Case &H20000049
        Case &H23000048
        Case &H24000032
        Case &H250001EE
        Case &H250001FE
        Case &H28000091
        Case &H2A0000E1
        Case &H2A0000F1
        Case &H3000069C
        Case &H300006D4
        Case &H300006D7
        Case &H300007A8
        Case &H32000121
        Case &H3700008E
        Case &H40000081
        Case &H58000092
        Case &HC0002D0
        Case &HD0000E8
        Case &HE0001FD
        Case &HE000622
        Case Else: Exit Function
    End Select

You know you can do "Case &H10000021, &H10000050, etc...", right? Hopefully it's more efficient than running 35 case checks, too...

Edit: Also, I tried logging in, and noticed something I find quite funny. The icon for my account (RealityRipple) on Warcraft 2, has the #1 IronMan icon next to it, even though I'm #33.

I'm sorry, I had to laugh out loud when I saw this:









wait a minute, nothing
hmmm...
expect realityripple bot have a 'warden bypass' in the next 24 hours. no thanks to ringo, either.
<3 Zorm
Quote[01:08:05 AM] <@Zorm> haha, me get pussy? don't kid yourself quik
Scio te esse, sed quid sumne? :P

Barabajagal

My bot doesn't have a warden bypass. And won't. Ringo and Blake were helping me with one for a while, but I got tired of trying to do things in VB6 and PB when they should be done in assembly (which I can't write in), so I deleted all of it. I'm waiting till Blake writes JBLS in C and then he or I will convert it to a nice little DLL like BNCSutil and we'll have a good library again.

|