• Open Steamworks
    616 replies, posted
  • Avatar of AzuiSleet
  • [QUOTE=ZeekyHBomb;17696839]Well, you still need to be logged into Steam if you want to use most (all?) parts of the Steamworks API. And I don't think you can log into the Steam Servers with the Steamworks API.[/QUOTE] You don't have to be on steam to use some of the API. You can make a game server account and sign on and use the ISteamGameServer and a couple other interfaces, without steam running.
  • Avatar of VoiDeD
  • Committed a usage example for ISteamGameServer and ISteamGameServerItems. [cpp] ISteamGameServer009 *gameServer = (ISteamGameServer009 *)steamClient->GetISteamGameServer(user, pipe, STEAMGAMESERVER_INTERFACE_VERSION_009); if (!gameServer) Error("Unable to get game server."); if ( !gameServer->SetServerType( k_unServerFlagNone | k_unServerFlagPrivate, // flags INADDR_ANY, // bind address 27016, // game port 0, 0, // query spectate ports "tf", // game dir "bullshit version string", // version false) ) { Error("Unable to set server mode."); } // start the server gameServer->LogOn(); ISteamGameServerItems004 *items = (ISteamGameServerItems004 *)steamClient->GetISteamGenericInterface(user, pipe, STEAMGAMESERVERITEMS_INTERFACE_VERSION_004); if (!items) Error("Unable to get server items."); // coolest person in the world CSteamID voided((uint64)76561197969249708L); HSteamCall hSteamCall; CallbackMsg_t CallbackMsg; while (!GetAsyncKeyState(VK_ESCAPE)) // loop until we escape { if (Steam_BGetCallback(pipe, &CallbackMsg, &hSteamCall)) { switch (CallbackMsg.m_iCallback) { case SteamServersConnected_t::k_iCallback: std::cout << "Now connected to the steam servers." << std::endl; // get an item count, triggers the below callback eventually items->GetItemCount(voided); break; case GSItemCount_t::k_iCallback: { GSItemCount_t *itemCallback = (GSItemCount_t *)CallbackMsg.m_pubParam; std::cout << "Result: " << EnumString<EItemRequestResult>::From(itemCallback->m_eResult) << std::endl; std::cout << "AppID: " << itemCallback->m_gameID.AppID() << std::endl; std::cout << "Count: " << itemCallback->m_unCount << std::endl << std::endl; for (uint32 x = 0; x < itemCallback->m_unCount; x++) { ItemID itemid; uint32 itemtype; uint32 itemlevel; EItemQuality quality; uint32 flags; uint32 quantity; uint32 nAttribs; if (!items->GetItemIterative(voided, x, &itemid, &itemtype, &itemlevel, &quality, &flags, &quantity, &nAttribs)) { std::cout << " * An error occurred while getting item #" << x << std::endl; continue; } std::cout << " * Item #" << x << ", id: " << itemid << ", type: " << itemtype << ", level: " << itemlevel << std::endl; std::cout << " quality: " << EnumString<EItemQuality>::From(quality) << std::endl; std::cout << " flags: " << flags << ", quantity: " << quantity << ", attribs: " << nAttribs << std::endl; } } break; default: std::cout << "Unhandled callback: " << CallbackMsg.m_iCallback << std::endl; } Steam_FreeLastCallback(pipe); } Sleep(10); } [/cpp] Check [url]http://code.assembla.com/steamworks/subversion/nodes/steamworks/main.cpp[/url] for the full example. [code] Now connected to the steam servers. Unhandled callback: 115 Unhandled callback: 703 Result: k_EItemRequestResultOK AppID: 8983980 Count: 34 * Item #0, id: 18446744073709545427, type: 121, level: 100 quality: k_EItemQuality_Unique flags: 2147745803, quantity: 1, attribs: 1 * Item #1, id: 8812982, type: 60, level: 5 quality: k_EItemQuality_Unique flags: 2155872283, quantity: 1, attribs: 0 * Item #2, id: 11259262, type: 43, level: 7 quality: k_EItemQuality_Unique flags: 2147483666, quantity: 1, attribs: 0 * Item #3, id: 11864486, type: 59, level: 5 quality: k_EItemQuality_Unique flags: 2147483676, quantity: 1, attribs: 0 * Item #4, id: 11896805, type: 56, level: 10 quality: k_EItemQuality_Unique flags: 2147483655, quantity: 1, attribs: 0 * Item #5, id: 12497217, type: 42, level: 1 quality: k_EItemQuality_Unique flags: 2147483667, quantity: 1, attribs: 0 [/code]
  • Avatar of subwar
  • incoming lol [cpp] uint64 gameID = 0; uint32 gameIP = 0; uint16 gamePort = 0; uint16 queryPort = 0; int numfriends = steamFriends->GetFriendCount(k_EFriendFlagImmediate); char GameInfo[255]; char *dot_ip; struct in_addr addr; for(int p=1;p < numfriends;p++){ CSteamID friendp = steamFriends->GetFriendByIndex(p,k_EFriendFlagImmediate); EChatEntryType Testmsg(k_EChatEntryTypeChatMsg); if(steamFriends->GetFriendPersonaState(friendp) == k_EPersonaStateOnline) { if((int64)steamFriends->GetFriendGamePlayed(friendp, &gameID, &gameIP, &gamePort, &queryPort)) { printf("gameID: %i\n", gameID); addr.s_addr = htonl(gameIP); dot_ip = inet_ntoa(addr); printf("%s\n",dot_ip); sprintf(GameInfo,"You are currently playing on %s", dot_ip); steamFriends->SendMsgToFriend(friendp,Testmsg,GameInfo,256); } } //GetFriendGamePlayed Sleep(25); } [/cpp]
  • Avatar of VoiDeD
  • Committed lots of new interfaces. ISteamFriends004, ISteamUtils003, ISteamNetworking001, ISteamNetworking003, and something fresh: IP2PController. IP2PController seems to be related to the torrent downloading features of steam.. Don't think they ever got implemented though.. [sp]If I get banned for mentioning the word "torrent", I will hate you all. :|[/sp] Anyhow it looks interesting enough: [url]http://code.assembla.com/steamworks/subversion/nodes/steamworks/IP2PController.h[/url] How to get your hands on one: [cpp] int error; ISteamClient008 *steamClient = (ISteamClient008 *)CreateInterface(STEAMCLIENT_INTERFACE_VERSION_008, &error); IClientEngine *engine = (IClientEngine *)CreateInterface(CLIENTENGINE_INTERFACE_VERSION, &error); HSteamPipe pipe = steamClient->CreateSteamPipe(); HSteamUser user = steamClient->CreateLocalUser(&pipe, k_EAccountTypeGameServer); // this can also be a regular global user IP2PController *p2p = (IP2PController *)engine->GetIP2PController(user, pipe, P2PCONTROLLER_INTERFACE_VERSION); if (!p2p) Error("No p2p."); [/cpp] [editline]03:43AM[/editline] Also again I'd like to reiterate about our IRC channel: irc.gamesurge.net / #opensteamworks This is the single best way to contact me, ask me questions, mentally destroy me with abusive language, etc.
  • Avatar of Jimbomcb
  • I'm having some really wierd issues, I'm sending a command to a steam client, it sees that I typed whatever and sends a reply EG [quote] jim is loading server status... (Updating in 41 seconds) jim Server: Playstuff TF2 Teamplay jim IP: 81.19.219.104:27015 jim Current Map: pl_goldrush jim Players: 0/24 jim --------------------- jim Server: The Map Lab | playportal.net | tf2maps.net jim IP: 84.45.84.166:27015 jim Current Map: cp_dustbowl jim Players: 0/25 jim has finished loading server status...[/quote] that is what is being sent and I can see that in the steam chat window from the bot, however... all that is appearing in the chat of the other person is [quote] 2:56 PM - jim 2:56 PM - jim 2:56 PM - jim 2:56 PM - jim 2:56 PM - jim 2:56 PM - jim --------------------- 2:56 PM - jim 2:56 PM - jim 2:56 PM - jim 2:56 PM - jim [/quote] what am I doing wrong? [cpp]char sInfo[256]; sprintf (sInfo, "Server: %s", res2->getString("name").c_str()); steamFriends->SendMsgToFriend(chatMsg->m_ulOtherID, msgTypeChat, sInfo, strlen(sInfo)); sprintf (sInfo, "IP: %s", res2->getString("ip").c_str()); steamFriends->SendMsgToFriend(chatMsg->m_ulOtherID, msgTypeChat, sInfo, strlen(sInfo)); sprintf (sInfo, "Current Map: %s", res2->getString("map").c_str()); steamFriends->SendMsgToFriend(chatMsg->m_ulOtherID, msgTypeChat, sInfo, strlen(sInfo)); sprintf (sInfo, "Players: %s", res2->getString("players").c_str()); steamFriends->SendMsgToFriend(chatMsg->m_ulOtherID, msgTypeChat, sInfo, strlen(sInfo)); [/cpp] [editline]03:15PM[/editline] now most of the messages i'm sending aren't even getting through, they are only showing up as blank :/
  • Avatar of Skondra
  • [QUOTE=Jimbomcb;17706963]I'm having some really wierd issues, I'm sending a command to a steam client, it sees that I typed whatever and sends a reply EG that is what is being sent and I can see that in the steam chat window from the bot, however... all that is appearing in the chat of the other person is what am I doing wrong? [cpp]char sInfo[256]; sprintf (sInfo, "Server: %s", res2->getString("name").c_str()); steamFriends->SendMsgToFriend(chatMsg->m_ulOtherID, msgTypeChat, sInfo, strlen(sInfo)); sprintf (sInfo, "IP: %s", res2->getString("ip").c_str()); steamFriends->SendMsgToFriend(chatMsg->m_ulOtherID, msgTypeChat, sInfo, strlen(sInfo)); sprintf (sInfo, "Current Map: %s", res2->getString("map").c_str()); steamFriends->SendMsgToFriend(chatMsg->m_ulOtherID, msgTypeChat, sInfo, strlen(sInfo)); sprintf (sInfo, "Players: %s", res2->getString("players").c_str()); steamFriends->SendMsgToFriend(chatMsg->m_ulOtherID, msgTypeChat, sInfo, strlen(sInfo)); [/cpp] [editline]03:15PM[/editline] now most of the messages i'm sending aren't even getting through, they are only showing up as blank :/[/QUOTE] I think you have to add 1 to the message length.
  • Avatar of VoiDeD
  • [QUOTE=Jimbomcb;17706963]I'm having some really wierd issues, I'm sending a command to a steam client, it sees that I typed whatever and sends a reply EG that is what is being sent and I can see that in the steam chat window from the bot, however... all that is appearing in the chat of the other person is what am I doing wrong? [cpp]char sInfo[256]; sprintf (sInfo, "Server: %s", res2->getString("name").c_str()); steamFriends->SendMsgToFriend(chatMsg->m_ulOtherID, msgTypeChat, sInfo, strlen(sInfo)); sprintf (sInfo, "IP: %s", res2->getString("ip").c_str()); steamFriends->SendMsgToFriend(chatMsg->m_ulOtherID, msgTypeChat, sInfo, strlen(sInfo)); sprintf (sInfo, "Current Map: %s", res2->getString("map").c_str()); steamFriends->SendMsgToFriend(chatMsg->m_ulOtherID, msgTypeChat, sInfo, strlen(sInfo)); sprintf (sInfo, "Players: %s", res2->getString("players").c_str()); steamFriends->SendMsgToFriend(chatMsg->m_ulOtherID, msgTypeChat, sInfo, strlen(sInfo)); [/cpp] [editline]03:15PM[/editline] now most of the messages i'm sending aren't even getting through, they are only showing up as blank :/[/QUOTE] Interesting.. It could be an issue with the message type you're using. Older versions of ISteamFriends used a different enumeration for their types than the newest ones, so I'm not sure if they changed how the values are handled internally. But since the "----------------" message gets through, this does seem very strange... There is probably something wrong with the size of the strings your sending, double check all your parameters to make sure they're correct.
  • Avatar of B1N4RY
  • [QUOTE=gngbng;17683260]there's been a public but limited steam api for a while[/QUOTE] Really? I didn't know...
  • Avatar of efeX
  • [QUOTE=Ortzinator;17711744]Someone make a tool to invite your entire friend's list to play a game.[/QUOTE] :O yeah
  • Avatar of raBBish
  • [url=http://codepad.org/LZysGdp6]Something like this?[/url] :buddy: It's untested, but should work. [editline]02:12AM[/editline] Improved version, won't send invites to people other than online. [url]http://codepad.org/r1f4eetF[/url]
  • Avatar of VoiDeD
  • I've committed the start of some experimental new code that might allow OSW to travel in another direction: game development. [url]http://code.assembla.com/steamworks/subversion/nodes/steamworks/main.cpp[/url] I didn't get much done tonight, so it isn't much now... but I'm going to try to evolve it into some sort of server/client architecture running entirely off of OSW's interfaces. Hopefully I can turn this into some sort of proof of concept of the usefulness of using this client set of interfaces without requiring access to the real steamworks. We'll see in time.
  • Avatar of mastersrp
  • [QUOTE=VoiDeD;17722008]I've committed the start of some experimental new code that might allow OSW to travel in another direction: game development. [url]http://code.assembla.com/steamworks/subversion/nodes/steamworks/main.cpp[/url] I didn't get much done tonight, so it isn't much now... but I'm going to try to evolve it into some sort of server/client architecture running entirely off of OSW's interfaces. Hopefully I can turn this into some sort of proof of concept of the usefulness of using this client set of interfaces without requiring access to the real steamworks. We'll see in time.[/QUOTE] What i would find really internesting would be a wiki :P I have almost no idea what i'm doing when using this.. Not that i'm that experienced with C++ either, so that could be the thing.
  • Avatar of VoiDeD
  • Well there is [url]http://steamworks.assembla.com/wiki/show/steamworks/Interface_Overview[/url], but it's lacking... If you or anyone else is interested in writing articles on the wiki just let me know, I'm always looking for help. [b]Edit[/b]: I've finished the server/client example code: [url]http://code.assembla.com/steamworks/subversion/nodes/steamworks/main.cpp[/url] What it does in a nutshell: Attempts a fake connection handshake between a client and a server. Currently it uses the TF2 AppID (440), so it requires ownership of the game in order for it to work. This is basically how the tf2 idler works, but without the added bonus of getting items. I'm still looking into that. As for how safe this would be to your current items, I really don't know. The way I'm assuming valve knew who idled is based on the IP of the servers they connected to. If you connected to the IP of drunken_f00l's servers, you got items removed. If this is truly the case, then any new idling should be entirely safe. But as I said, I have no idea. :)
  • Avatar of VoiDeD
  • An update on the project. I've started work on yet another new aspect of Open Steamworks that will enable more developers to get access to the code base: dotnetworks. dotnetworks is a managed C++/CLI wrapper of the OSW code that allows developers in the .NET environment to access the interfaces. The dotnetworks project will allow C# programmers, for example, to get the same features and functionality from OSW. [cpp] static class Program { static void Main() { if ( !Steamworks.Init() ) { MessageBox.Show( "Unable to initialize steamworks." ); return; } SteamUserStats002 stats = Steamworks.GetSteamUserStats002(); GameID tf2 = new GameID( 440 ); if ( !stats.RequestCurrentStats( tf2 ) ) Console.WriteLine( "Can't get stats." ); uint numStats = stats.GetNumStats( tf2 ); for ( uint x = 0 ; x < numStats ; x++ ) { string name = stats.GetStatName( tf2, x ); int value = 0; bool success = stats.GetStat( tf2, name, ref value ); if ( success ) Console.WriteLine( name + ": " + value ); } } } [/cpp] But, mind you, this project is only in its infancy, and will require a great deal of work until the major features are implemented. In order for dotnetworks to expand, I need alot of assistance. The process of writing wrapper classes for each of the interfaces in OSW is a very lengthy process that requires a large investment of time. Currently the OSW team looks like this: [url]http://www.assembla.com/spaces/steamworks/team[/url], and I'm always looking for anyone who is willing to put forward any amount of effort to help support the project. [b]So I'm asking for anyone that can help commit code changes and new classes to dotnetworks, so that aspect of the project can expand. Please send me a PM, contact me on IRC, or send off an email to [email]voidedweasel@gmail.com[/email] if you are interested. Thanks![/b]
  • Avatar of VoiDeD
  • Yes, but it's recommended you use the one in the ISteamFriends interfaces. Unless you're referring to dotnetworks, in which case no, neither the ISteam nor the IClient friend interfaces are implemented yet.
  • Avatar of id3z
  • normal steamworks, yeah. i mean [cpp]virtual bool SendChatMsg( CSteamID steamIDFriend, EChatEntryType eChatEntryType, const void *pvMsgBody, int cubMsgBody ) = 0;[/cpp] in IClientFriends.h. i'm assuming that one is to send messages in multi-user chats and not just 1on1 friend IMs? because all i see in the ISteamFriends is [cpp]virtual bool SendMsgToFriend( CSteamID steamIDFriend, EFriendMsgType eFriendMsgType, const void *pvMsgBody, int cubMsgBody ) = 0;[/cpp]
  • Avatar of VoiDeD
  • I think SendChatMsg sends to friends only. As for the enums, the EFriendMsgType is generally the one used in the newest interfaces, and I don't know if the older ones translate EChatEntryType to those, or just handle those themselves. Edit: :woop: Page 3!
  • Is this safe to mess around with? I know it doesn't touch VAC but would valve approve/take action? [editline]09:46PM[/editline] Not too bothered, just wondering.
  • Avatar of AzuiSleet
  • Valve could change their policy on using leaked and stolen documents and ban your account.
  • Avatar of Sippeangelo
  • [QUOTE=qurl;17762132]Is this safe to mess around with? I know it doesn't touch VAC but would valve approve/take action? [editline]09:46PM[/editline] Not too bothered, just wondering.[/QUOTE] Remember the achievement unlocker and idler?
  • Avatar of VoiDeD
  • [QUOTE=Sippeangelo;17762662]Remember the achievement unlocker and idler?[/QUOTE] That situation was a specific case. It's impossible to know if the game is editing achievements/stats, or if an outside program is doing so. But it's easy for them to track when people unlocked them. So if they check their databases for players who unlocked the majority of the achievements in a few seconds/minutes, it's a no brainer for them. The idler was only because Valve changed their policies in regards to using external programs to get items. It's possible that using OSW in this same fashion could get people's items removed, but so far nothing has happened from running my own idler on localhost. Could support the theory that valve only monitored what servers clients connected to.
  • Avatar of Nisd
  • If any one is to lazy to compile it on their own, then i made a build bot just for the fun of it. [url]http://server1.hiddenservers.org/build/Open%20Steamworks/[/url]
  • Avatar of Ortzinator
  • Valve got pissed because a few users were gaming the system and devaluing the items that other users got legitimately. Like inflation. This is nothing like that.
  • Avatar of VoiDeD
  • Another interesting example of what is possible with OSW: [img]http://dl.getdropbox.com/u/99606/irc_relay.png[/img] I'd also mention that this is a C# project, running on top of dotnetworks. All the code for this is available on the SVN.
  • Avatar of General1337
  • This is pretty cool, I made a winamp name changer thing or w/e. [img]http://www.moogen.org/other/winampplugin.jpg[/img]