Entries:
Comments:
Posts:

Loading User Information from Channel 9

Something went wrong getting user information from Channel 9

Latest Achievement:

Loading User Information from MSDN

Something went wrong getting user information from MSDN

Visual Studio Achievements

Latest Achievement:

Loading Visual Studio Achievements

Something went wrong getting the Visual Studio Achievements

TweetCraft - An in-game Twitter client for World of Warcraft

TweetCraft is a World of Warcraft add-on that enables you to send and receive tweets using Twitter without leaving the game, automatically upload and post screenshots using TwitPic and automatically tweet certain in-game events such as achievements and moving around in the world of Azeroth. TweetCraft customizes your World of Warcraft user interface by adding its own frame similar to the built-in ones (such as the Quest Log) and provides easy access to it through a button near the minimap, slash commands or your favorite launcher (e.g. ChocolateBar).

How TweetCraft works

Let’s quickly walk through the different things that TweetCraft does to bring Twitter into World of Warcraft.

Overview

World of Warcraft’s user interface is highly customizable and enables add-on developers to do almost anything in the game they can dream of. Add-ons can interact with the world, listen to events that happen in the game, alter the look of the default user interface or create brand new ones, but add-ons are seriously limited when it comes to talking to the world outside World of Warcraft. They cannot read or write files, call web services or do anything that could be potentially harmful. This is why TweetCraft comes with a Windows application that sits in the Notification Area (also known as the tray) and does the bulk of the work, giving the TweetCraft add-on only the data that it needs to display, such as tweets, replies and user pictures. All the Twitter web service calls, uploading of screenshots and housekeeping is done by this application. Let’s see how!

The TweetCraft Tray application

The TweetCraft Tray application is a WPF application that periodically checks for new tweets, dowloads and converts the user pictures of the tweets’ authors and writes it out to a file that World of Warcraft picks up and the add-on can use. It also picks up all outgoing tweets queued up for sending and sends them using Twitter one-by-one. It watches for screenshots taken by World of Warcraft and uploads them using TwitPic immediately.

To do all this, it has a couple of settings that need to be configured before it can work. For starters, it needs your Twitter credentials to be able to send tweets and post pictures on your behalf. It also needs to know which World of Warcraft account you are going to use to play and send and receive tweets with. Finally, you can opt out of automatically uploading screenshots you take during game. Figure 1 shows the TweetCraft Settings window that shows up when you first start TweetCraft after installation and is also available by right clicking the tray icon (Figure 2).

Figure1_TweetCraftSettingsWindow
Figure 1. TweetCraft Settings Window

Figure2_TweetCraftTrayIcon
Figure 2. TweetCraft tray icon in the notification area

Getting data from Twitter

TweetCraft uses an open-source library called TwitterLib to send and receive tweets using Twitter’s API. TwitterLib is part of the open-source WPF Twitter Client WittyTwitter and wraps the web services provided by Twitter into an easy to use .NET class library. TweetCraft wraps this library into a simple class called TwitterClient that all the services in TweetCraft rely on. One of those services is the TwitterBackgroundService which polls Twitter periodically to check for new tweets. By default, this is set to five minutes. If new tweets or replies are available, an event is raised that other components of TweetCraft can handle and work with the new tweets, download user pictures, etc. Figure 3 shows the three classes that take part in downloading new tweets and replies and notifying other classes.

Figure3_TwitterBackgroundService
Figure 3. TwitterBackgroundService, TwitterClient and TwitterNet (TwitterLib)

 

Dynamically building TGA images

When it comes to visualizing images (or textures, in WoW parlance), World of Warcraft poses quite a few restrictions on what files can be used and where does files should be. First of all, World of Warcraft only supports the TGA and BLP file formats. TGA stands for the Truevision Targa format, whereas BLP is Blizzard’s own image format. The images must also have dimensions of two (32×32, 64×64 pixels and so on…), otherwise they won’t show up. On the other hand, Twitter user pictures are available as 48×48 or 75×75 pixels and in various well-known formats, such as JPG, PNG or even GIF. TweetCraft needs to convert these pictures to 64×64 TGA files if it wants to play nice with World of Warcraft. This is done for each tweet’s authors user picture that will show up in World of Warcraft. The converted pictures must be placed in the Interface folder of World of Warcraft where the add-ons themselves also reside. The TwitterUserPictureService can retrieve the user picture and convert it to a 64×64 TGA file that contains the 48×48 user picture in the middle and puts that file into the same directory where the TweetCraft add-on is installed. The files are named after each user’s screen name and if TwitterUserPictureService sees that a file is already there, it won’t convert it again, saving some time and computing power.

Figure 4 shows TwitterUserPictureService and two helper classes that take care of downloading and the actual conversion. The GetUserPicturePath method returns the path of the resulting World of Warcraft compatible TGA file for a single user.

Figure4_TwitterUserPictureService
Figure 4. TwitterUserPictureService and its helper classes

Serializing tweets into Lua

Until now, we were quite secretive about how we can avoid World of Warcraft’s restrictions and let TweetCraft be able to read the data and show it. We’ve said that add-ons cannot read or write files and that still hasn’t changed during the last few minutes, but add-ons must have a way somehow to save their settings and other information when I log out of the game and load that when I log back in, you sincerely ask and you’re right! Although add-ons cannot read or write to files, they can ask World of Warcraft to save and load some of their global variables whenever the user reloads the UI (by entering an instance or hearthing), logs in or logs out. These files are called the SavedVariables files. When TweetCraft finishes downloading tweets, converting user pictures and everything else, it saves them using the very same format and to the very same file World of Warcraft uses on behalf of the TweetCraft add-on. Neat, huh? Just wait a little bit more… Smiley

Those variables that an add-on asks to be saved between sessions are saved into a Lua file, which is the same programming language add-on developers can use to write their add-ons. So basically, World of Warcraft creates a file that contains code full of assignment statements (think a = 5) that it will just run whenever those values need to be set again. More complex data structures can also be expressed this way using Lua tables, the swiss army-knife of Lua.

It sounds like a great idea to put all the data we would like for TweetCraft to use, but all we have is .NET objects, arrays and dictionaries. Fortunately, all these data structures can be expressed with simple Lua types and tables and TweetCraft comes with a class called LuaSerializer that produces Lua code from any .NET object (with a few restrictions, of course), very similar to how XmlSerializer works.

To make this even more simple, TweetCraft contains the concept of a SavedVariablesChannel that you can just drop objects in, flush it and those object show up on the other side. In our case, as Lua variables. What’s even better, it works the other way around as well. The TweetCraft add-on stores all the tweets queued up and ready to be sent in a variable and triggers World of Warcraft to save them to the SavedVariables file. The SavedVariablesChannel detects this by watching for changes made to the SavedVariables file using FileSystemWatcher and notifies other components of the TweetCraft application that can pull out the information and send the tweets.

Figure 5 shows SavedVariablesChannel and its base class, ValueChannelBase which keeps track of all objects thrown into it until it is flushed.

Figure5_SavedVariablesChannel
Figure 5. SavedVariablesChannel and ValueChannelBase

Refreshing the data in World of Warcraft

There’s one last problem we face when trying to achieve this two-way communication between the TweetCraft add-on and the application. If World of Warcraft is running, we cannot just overwrite the SavedVariables file and expect World of Warcraft to pick it up as it does not watch for changes made to the file. If we were to overwrite the file and subsequently the user logs out, World of Warcraft will happily overwrite the information we placed there. There’s another trick we have to resort to: the TweetCraft add-on can trigger the reloading of the UI which will unload all add-ons, save their variables and then load them again. There’s a a little bit of time between the saving and loading of a particular add-ons SavedVariables file and that’s when TweetCraft can safely read the file for queued up tweets and overwrite it with the new data. This is what happens when the user clicks the Refresh button in TweetCraft’s frame.

Sending tweets and uploading screenshots

Whenever the user queues up tweets for sending, they are not immediately sent but kept in a data structure that will be saved out to the SavedVariables file by World of Warcraft. We’ve seen that his happens when either the user logs out or presses the Refresh button. The updated SavedVariables file gets detected by SavedVariablesChannel and the ChannelUpdated event is raised. When the TweetCraft application handles this event, it cannot immediately send the tweets as that would take a couple seconds and if you remember from the last section, we only have a tiny little window of time to process the values and save back all the data we would like to send back. For this reason, the tweets that are picked up from the SavedVariables file using the SavedVariablesChannel get quickly queued up in the TwitterDispatcherService that then goes ahead and starts sending them one by one in the background. To make sure that all the values we prepared to save into the file get flushed, the SavedVariablesChannel has a property called AutoFlush that is enabled by default.

One thing we have not mentioned is that TwitterDispatcherService can also upload and post pictures using TwitPic. It watches the Screenshots folder of World of Warcraft for new files and if AutoTweeting of screenshots is enabled, immediately queues up the picture for uploading and posting it. This also means that you don’t need to press the Refresh button or wait until you log off for screenshots to be posted. They will show up immediately in your Twitter feed.

The TwitterDispatcherService uses TwitterClient (and TwitterLib) to send the tweets but it does not interfere with the quick reading and writing of the SavedVariables file we discussed previously. It also uses TwitPicClient to upload and post pictures. Figure 6 shows TwitterDispatcherService, TwitterClient and TwitPicClient.

Figure6_TwitterDispatcherService
Figure 6. TwitterDispatcherService, TwitterClient and TwitPicClient

Bringing it all together

So far, we’ve looked at components of TweetCraft that implemented a particular part of the application. Retrieving and sending tweets, converting user pictures and making all this information available for the TweetCraft add-on, but there’s an important class that brings all this together and contains all the logic of how these components interact with each other. We also need to be able to detect World of Warcraft installations, figure out what accounts are available and where to look for files like the SavedVariables files and put the converted user pictures. The TweetCraft class implements the logic required and relies on the WorldOfWarcraft class for everything World of Warcraft related.

Figure 7 shows the TweetCraft and WorldOfWarcraft side by side.

Figure7_TweetCraft
Figure 7. TweetCraft and WorldOfWarcraft

Summary

While this is a high-level overview of TweetCraft only, it gives you a good idea of how it enables World of Warcraft players to use Twitter to send and receive tweets, upload the screenshots and share their achievements right inside the game. Make sure you try out TweetCraft if you have World of Warcraft installed and if you’re curious, download the source code and take a deeper look.

 


Gabor Ratky (Blog, Twitter), Senior Software Engineer and Coding4Fun Ninja at EPAM Systems 

Gabor is the developer behind TweetCraft and has been working on Coding4Fun projects for almost two years. He also leads the development of AddOn Studio for World of Warcraft, a Visual Studio-based IDE for building World of Warcraft add-ons and he co-authored the chapter in the Coding4Fun book about it. He is a VSX Insider and was invited to speak at various events about Visual Studio Extensibility. When not working on Coding4Fun projects, Gabor works on large scale, enterprise solutions using exciting Microsoft technologies. He lives in Budapest, Hungary and loves traveling, good wine and Channel9 videos.

Tags:

Follow the Discussion

  • KFMKFM

    Isn't this a violation of Blizz's ToS/CoC for WoW?

  • RevDanCattRevDanCatt

    Nice app, been thinking about this for a while myself, but don't have the time along with everything else ... and it's a bit of a pain having to reload the UI, jarring for the user ... so here's a couple of thoughts I had, for getting tweets out...

    1) If the tweet isn't *super* time critical you may want to look at writing to the players event calendar...

    Pick a day in the far future and write a "twitter:my twitter here event". It takes about 5mins for the data to propagate to the users events calendar on the WoW website. Your tray app, if given the credentials can poll the WoW site for the user's Calendar in XML format for that month. It's a slow way to get info out, but it works.

    Or ...

    2) Or, convert the tweet to binary and write the binary out as pixels along the top and bottom couple of lines of pixels on the screen (add checksums if you need to). Then dump the screenshot, your app checks for the screenshot and reads the pixels from the top and bottom converting them back to text ... etc.

    Both of these don't need the UI reload.

    *But* sadly you do need the reload as you're doing to display tweets. For a one way getting info out though it should work, and I haven't seen the methods documented anywhere else Smiley

  • Fang XianfuFang Xianfu

    Apologies, it's heading III, not I.

  • Fang XianfuFang Xianfu

    Note: this sort of interaction with a third-party executable is exactly what Blizzard's Terms of Use (http://www.wow-europe.com/en/legal/termsofuse.html) explicitly forbid.

    See heading I, section 3, sub-sections 1: "You agree that you will not modify or cause to be modified any files that are a part of a World of Warcraft installation"; 2: "You agree that you will not.. use.. any other third-party software designed to modify the World of Warcraft experience"; and 3: "You agree that you will not use any third-party software that... collects information from or through World of Warcraft"

    Your account may be at risk if you use this software.

  • KlausKlaus

    Cool!I love twitter,I love this.

  • RobRob

    Hi, I don't really play WoW anymore, but I was really intrigued by this mod as I know communicating with external programs is very difficult from WoW LUA.

    Do you think Blizzard will have a problem with this? I'm not very familiar with the WoW EULA/TOS but it seems like Blizzard does not like the thought of WoW addon's communicating with an external program( please correct me on this if i'm wrong)  and this might be against their wishes.

    Regardless this is a very cool piece of coding, thanks for releasing the source and I wish you all the best!

  • RenmiriRenmiri

    Yay for this!

    I had thought about writing some simple guild chat to tweeter bridge, to be able to keep up with guildies while I'm at work, but as you found out it turned out to not be so simple Tongue Out

    Your addon is perfect for what I wanted! TY, TY, TY!!!

  • AnthonyAnthony

    As I expected, as a fellow LUA programmer, this completely got blown out of proportion.  You STILL have to do a UI reload if you want to get new data, so this has basically already been done before by the ***numerous*** addons such as thottbot's old 'armory' back before armory existed.

    This doesn't do any meaningful communication at all.  Great concept, but Blizzard really should open the API to outside app communication, for things such as IM clients, and this particular program.

  • Ian RobinsonIan Robinson

    Have you been in communication with Blizzard to make sure that Tweetcraft does not break any Terms of Service for the game?

  • vendita diretta vinovendita diretta vino

    Wow, I never knew that An in-game Twitter client for World of Warcraft. That's pretty interesting...

  • vino del monferratovino del monferrato

    I was just thinking about The TweetCraft Tray application and you've really helped out. Thanks!

  • barbera del monferratobarbera del monferrato

    That's great, I never thought about An in-game Twitter client for World of Warcraft like that before.

  • danielfedanielfe

    I already responded to Fang Xianfu in the Frequently Asked Questions from TweetCraft. Link: http://tweetcraft.codeplex.com/Wiki/View.aspx?title=Frequently%20Asked%20Questions

    Comment

    - "You agree that you will not modify or cause to be modified any files that are a part of a World of Warcraft installation"

    - Tweetcraft modifies part of the WTF folder.

    Response

    - Incorrect: TweetCraft only reads/writes from the TweetCraft.lua file that it installs. TweetCraft is not part of the World of Warcraft installation

    Comment

    - "You agree that you will not create or use... any other third-party software designed to modify the World of Warcraft experience"

    - TweetCraft is a third-party executable that "modifies the World of Warcraft experience". The fact that it doesn't edit the memory doesn't matter.

    Response

    - The TweetCraft executable saves data to a file, it doesn't alter the World of Warcraft experience alone. In fact, you could have the executable running all day and it would have no affect on the experience

    - As others have pointed out, addons are designed to alter the 3rd party experience.

    Comment

    - "You agree that you will not use any third-party software that intercepts, "mines", or otherwise collects information from or through World of Warcraft"

    - TweetCraft collects information (your outgoing tweets) from World of Warcraft.

    Response

    - The data mining clause was to prevent addons that would provide gold prices for auction house or population addons (Cosmo, which is still not banned)

    - TweetCraft only collects information that you decide to share. If you load TweetCraft and you send no outgoing tweets, the TweetCraft addon has done nothing wrong. Would you ban the Notepad addon (http://wow.curse.com/msgs/default.aspx?MessageId=9? ) if a user "datamines" information by recording what's important to them while playing Warcraft?

    Comment

    - Claiming its open source and can't be stopped in a terrible argument. Blizzard can stop it and most likely will. I don't agree with the policy but its the policy. *Frustration*

    Response

    - The only reason I mention it's open source is for the security aspects of the application as some folks thought this was a keylogger

    Not Just TweetCraft

    The techniques we're doing are the same exact ones used by the wowhead, curse, or WowWebStats clients do for quite some time. We're not really doing anything new here and those have *not* been banned. This could absolutely change in the future though.

    Contacting Blizzard

    In terms of getting clarity from Blizzard, some folks have asked on the forums already, but a "blue" didn't respond. Additionally, before we ever shipped, I personally sent two emails to wowui@blizzard.com from my Microsoft.com email address:

    First email: April 15, 2009, Subject: Clarifications on new AddOn rules

    Second email: May 26, 2009, Subject: Re: Clarifications on new AddOn rules

    In the second email, I said "Assuming we don’t hear back from you, we’re going to assume that what we’re doing is not a violation of the new UI AddOn development policy." I did receive their auto-responder saying they have received my email for the May 26th email. I NEVER received a response that this was in violation.

    If we do receive a warning, we'll post the note, explain what's happening, and stop working on TweetCraft. We're not trying to get anyone banned.

    Hope this helps,

    -Dan

    Project Coordinator

  • danielfedanielfe

    Ian - I personally tried emailing Blizzard Entertainment twice (to wowui@blizzard-dotcom) and never received a response from them. We did work with Blizzard directly when we first launched AddOn Studio for World of Warcraft where we showed off the same techniques to build an in-game RSS Reader (circa 2007).

    We don't think it violates the Terms of service and it does effectively what other clients like the Curse, Wowhead or WowWebStats clients do.

    Someone has asked on the forums for a response from Blizzard as well, but they haven't heard back. I don't think this breaks the TOS as we are only synchronizing data into Lua variables, much like Wowhead's quest helper.

    If we hear back, we'll let you know.

    Thanks,

    -Dan

    Project Coordinator

  • chaudchaud

    Assuming it is you, please stop using the #wow tag, it is polluting the search.

  • Bruce StockwellBruce Stockwell

    I use TweetCraft with multiple windows logins and multiple Wow accounts. Each user has to make sure they shutdown TC before another user logs in to use it. "TweetCraft is already running" happens if you don't. Can I configure this app to live in each user space so that it can be left running for each user all the time? I wish I could leave feedback on your project page without having to have an account there.

  • fryyfryy

    Dose TweetCraft support twitter api proxy?

Remove this comment

Remove this thread

close

Comments Closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums,
or Contact Us and let us know.