Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7018 Articles
article-image-working-zend-framework-20
Packt
29 Aug 2013
5 min read
Save for later

Working with Zend Framework 2.0

Packt
29 Aug 2013
5 min read
(For more resources related to this topic, see here.) So, what is Zend Framework? Throughout the years, PHP has become one of the most popular server-side scripting languages on the Internet. This is largely due to its steep learning curve and ease of use. However, these two reasons have also contributed to many of its shortcomings. With minimal restrictions on how you write code with this language, you can employ any style or structure that you prefer, and thus it becomes much easier to write bad code. But there is a solution: use a framework! A framework simplifies coding by providing a highly modular file organization with code libraries of the most common scripting in everyday programming. It helps you develop faster by eliminating the monotonous details of coding and makes your code more re-usable and easier to maintain. There are many popular PHP frameworks out there. A number of them have large, open source communities that provide a wide range of support and offer many solutions. This is probably the main reason why most beginner PHP developers get confused while choosing a framework. I will not discuss the pros and cons of other frameworks, but I will demonstrate briefly why Zend Framework is a great choice. Zend Framework (ZF) is a modern, free, and open source framework that is maintained and developed by a large community of developers and backed by Zend Technologies Ltd, the company founded by the developers of PHP. Currently, Zend Framework is used by a large number of global companies, such as BBC, Discovery, Offers.com, and Cisco. Additionally, many widely used open source projects and recognized frameworks are powered by Zend Framework, such as in the case of Magento, Centurion, TomatoCMS, and PHProjekt. And lastly, its continued development is sponsored by highly recognizable firms such as Google and Microsoft. With all this in mind, we know one thing is certain—Zend Framework is here to stay. Zend Framework has a rich set of components or libraries and that is why it is also known as a component framework. You will find a library in it for almost anything that you need for your everyday project, from simple form validation to file upload. It gives you the flexibility to select a single component to develop your project or opt for all components, as you may need them. Moreover, with the release of Zend Framework 2, each component is available via Pyrus and Composer. Pyrus is a package management and distribution system, and Composer is a tool for dependency management in PHP that allows you to declare the dependent libraries your project needs and installs them in your project for you. Zend Framework 2 follows a 100 percent object-oriented design principle and makes use of all the new PHP 5.3+ features such as namespaces, late static binding, lambda functions, and closures. Now, let’s get started on a quick-start project to learn the basics of Zend Framework 2, and be well on our way to building our first Zend Framework MVC application. Installation ZF2 requires PHP 5.3.3 or higher, so make sure you have the latest version of PHP. We need a Windows-based PC, and we will be using XAMPP (http://www.apachefriends.org/en/xampp.html) for our development setup. I have installed XAMPP on my D: drive, so my web root path for my setup is d:xampphtdocs. Step 1 – downloading Zend Framework To create a ZF2 project, we will need two things: the framework itself and a skeleton application. Download both Zend Framework and the skeleton application from http://framework.zend.com/downloads/latest and https://github.com/zendframework/ZendSkeletonApplication, respectively. Step 2 – unzipping the skeleton application Now put the skeleton application that you have just downloaded into the web root directory (d:xampphtdocs) and unzip it. Name the directory address-book as we are going to create a very small address book application, or you can name it anything you want your project name to be. When you unzip the skeleton application, it looks similar to the following screenshot: Step 3 – knowing the directories Inside the module directory, there is a default module called Application. Inside the vendor directory, there is an empty directory called ZF2. This directory is for the Zend Framework library. Unzip the Zend Framework that you have downloaded, and copy the library folder from the unzipped folder to the vendorZF2 directory. Step 4 – welcome to Zend Framework 2 Now, in your browser, type: http://localhost/address-book/public. It should show a screen as shown in the following screenshot. If you see the same screen, it means you have created the project successfully. And that’s it By this point, you should have a working Zend Framework, and you are free to play around and discover more about it. Summary In this article we will learned what is Zend Framework and will also learn how to install it on Windows PC. Resources for Article: Further resources on this subject: Authentication with Zend_Auth in Zend Framework 1.8 [Article] Building Your First Zend Framework Application [Article] Authorization with Zend_Acl in Zend Framework 1.8 [Article]
Read more
  • 0
  • 0
  • 1693

article-image-what-are-ssas-2012-dimensions-and-cube
Packt
29 Aug 2013
7 min read
Save for later

What are SSAS 2012 dimensions and cube?

Packt
29 Aug 2013
7 min read
(For more resources related to this topic, see here.) What is SSAS? SQL Server Analysis Services is an online analytical processing tool that highly boosts the different types of SQL queries and calculations that are accepted in the business intelligence environment. It looks like a relation database, but it has differences. SSAS does not replace the requirement of relational databases, but if you combine the two, it would help to develop the business intelligence solutions. Why do we need SSAS? SSAS provide a very clear graphical interface for the end users to build queries. It is a kind of cache that we can use to speed up reporting. In most real scenarios where SSAS is used, there is a full copy of the data in the data warehouse. All reporting and analytic queries are run against SSAS rather than against the relational database. Today's modern relational databases include many features specifically aimed at BI reporting. SSAS are database services specifically designed for this type of workload, and in most cases it has achieved much better query performance. SSAS 2012 architecture In this article we will explain about the architecture of SSAS. The first and most important point to make about SSAS 2012 is that it is really two products in one package. It has had a few advancements relating to performance, scalability, and manageability. This new version of SSAS that closely resembles PowerPivot uses the tabular model. When installing SSAS, we must select either the tabular model or multidimensional model for installing an instance that runs inside the server; both data models are developed under the same code but sometimes both are treated separately. The concepts included in designing both data models are different, and we can't turn a tabular database into a multidimensional database, or vice versa without rebuilding everything from the start. The main point of view of the end users is that both data models do almost the same things and appear almost equally when used through a client tool such as Excel. The tabular model A concept of building a database using the tabular model is very similar to building it in a relational database. An instance of Analysis Services can hold many databases, and each database can be looked upon as a self-contained collection of objects and data relating to a single business solution. If we are writing reports or analyzing data and we find that we need to run queries on multiple databases, we probably have made a design mistake somewhere because everything we need should be contained within an individual database. Tabular models are designed by using SQL Server Data Tools (SSDT), and a data project in SSDT mapping onto a database in Analysis Services. The multidimensional model This data model is very similar to the tabular model. Data is managed in databases, and databases are designed in SSDT, which are in turn managed by using SQL Server Management Studio. The differences may become similar below the database level, where the multidimensional data model rather than relational concepts are accepted. In the multidimensional model, data is modeled as a series of cubes and dimensions and not tables. The future of Analysis Services We have two data models inside SSAS, along with two query and calculation languages; it is clearly not an ideal state of affairs. It means we have to select a data model to use at the start of our project, when we might not even know enough about our need to gauge which one is appropriate. It also means that anyone who decides to specialize in SSAS has to learn two technologies. Microsoft has very clearly said that the multidimensional model is not scrapped and that the tabular model is not its replacement. It is just like saying that the new advanced features for the multidimensional data model will be released in future versions of SSAS. The fact that the tabular and multidimensional data models share some of the same code suggests that some new features could easily be developed for both models simultaneously. What's new in SSAS 2012? As we know, there is no easy way of transferring a multidimensional data model into a tabular data model. We may have many tools in the market that claim to make this transition with a few mouse clicks, but such tools could only ever work for very simple multidimensional data models and would not save much development time. Therefore, if we already have a mature multidimensional implementation and the in-house skills to develop and maintain it, we may find the following improvements in SSAS 2012 useful. Ease of use If we are starting an SSAS 2012 project with no previous multidimensional or OLAP experience, it is very likely that we will find a tabular model much easier to learn than a multidimensional one. Not only are the concepts much easier to understand, especially if we are used to working with relational databases, but also the development process is much more straightforward and there are far fewer features to learn. Compatibility with PowerPivot The tabular data model and PowerPivot are the same in the way their models are designed. The user interfaces used are practically the same, as both the interfaces use DAX. PowerPivot models can be imported into SQL Server Data Tools to generate a tabular model, although the process does not work the other way around, and a tabular model cannot be converted to a PowerPivot model. Processing performance characteristics If we compare the processing performance of the multidimensional and tabular data models, that will become difficult. It may be slower to process a large table following the tabular data model than the equivalent measure group in a multidimensional one because a tabular data model can't process partitions in the same table at the same time, whereas a multidimensional model can process partitions in the same measure group at the same time. What is SSAS dimension? A database dimension is a collection of related objects; in other words, attributes; they provide the information about fact data in one or more cubes. Typical attributes in a product dimension are product name, product category, line, size, and price. Attributes can be organized into user-defined hierarchies that provide the paths to assist users when they browse through the data in a cube. By default these attributes are visible as attribute hierarchies, and they can be used to understand fact data in a cube. What is SSAS cube? A cube is a multidimensional structure that contains information for analytical purposes; the main constituents of a cube are dimensions and measures. Dimensions define the structure of a cube that you use to slice and dice over, and measures provide the aggregated numerical values of interest to the end user. As a logical structure, a cube allows a client application to retrieve values—of measures—as if they are contained in cells in the cube. The cells are defined for every possible summarized value. A cell, in the cube, is defined by the intersection of dimension members and contains the aggregated values of the measures at that specific intersection. Summary We talked about the special new features and services present, what you can do with them, and why they’re so great. Resources for Article: Further resources on this subject: Creating an Analysis Services Cube with Visual Studio 2008 - Part 1 [Article] Performing Common MDX-related Tasks [Article] How to Perform Iteration on Sets in MDX [Article]
Read more
  • 0
  • 0
  • 4453

article-image-getting-started-your-first-jquery-plugin
Packt
29 Aug 2013
9 min read
Save for later

Getting started with your first jQuery plugin

Packt
29 Aug 2013
9 min read
(For more resources related to this topic, see here.) Getting ready Before we dive into our development, we need to have a good idea of how our plugin is going to work. For this, we will write some simple HTML to declare a shape and a button. Each shape will be declared in the CSS, and then we will use the JavaScript to toggle which shape is shown by toggling the CSS class appended to it. The aim of this recipe is to help you familiarize yourself both with jQuery plugin development and the jQuery Boilerplate template. How to do it Our first step is to set up our HTML. For this we need to open up our index.html file. We will need to add two elements in HTML: shape and wrapper to contain our shape. The button for changing the shape element will be added dynamically by our JavaScript. We will then add an event listener to it so that we can change the shape. The HTML code for this is as follows: <div class="shape_wrapper"> <div class="shape"> </div> </div> This should be placed in the div tag with class="container" in our index.html file. We then need to define each of the shapes we intend to use using CSS. In this example, we will draw a square, a circle, a triangle, and an oval, all of which can be defined using CSS. The shape we will be manipulating will be 100px * 100px. The following CSS should be placed in your main.css file: .shape{ width: 100px; height: 100px; background: #ff0000; margin: 10px 0px; } .shape.circle{ border-radius: 50px; } .shape.triangle{ width: 0; height: 0; background: transparent; border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 100px solid #ff0000; } .shape.oval{ width: 100px; height: 50px; margin: 35px 0; border-radius: 50px / 25px; } Now it's time to get onto the JavaScript. The first step in creating the plugin is to name it; in this case we will call it shapeShift. In the jQuery Boilerplate code, we will need to set the value of the pluginName variable to equal shapeShift. This is done as: var pluginName = "shapeShift" Once we have named the plugin, we can edit our main.js file to call the plugin. We will call the plugin by selecting the element using jQuery and creating an instance of our plugin by running .shapeShift(); as follows: (function(){$('.shape_wrapper').shapeShift();}()); For now this will do nothing, but it will enable us to test our plugin once we have written the code. To ensure the flexibility of our plugin, we will store our shapes as part of the defaults object literal, meaning that, in the future, the shapes used by the plugin can be changed without the plugin code being changed. We will also set the class name of the shape in the defaults object literal so that this can be chosen by the plugin user as well. After doing this, your defaults object should look like the following: defaults = {shapes: ["square", "circle", "triangle", "oval"],shapeClass: ".shape"}; When the .shapeShift() function is triggered, it will create an instance of our plugin and then fire the init function. For this instance of our plugin, we will store the current shape location in the array; this is done by adding it to this by using this.shapeRef = 0. The reason we are storing the shape reference on this is that it attaches it to this instance of the plugin, and it will not be available to other instances of the same plugin on the same page. Once we have stored the shape reference, we need to apply the first shape class to the div element according to our shape. The simplest way to do this is to use jQuery to get the shape and then use addClass to add the shape class as follows: $(this.element).find(this.options.shapeClass).addClass(this.options.shapes[this.shapeRef]); The final step that we need to do in our init function is to add our button to enable the user to change the shape. To do this, we simply append a button element to the shape container as follows: $(this.element).append('<button>Change Shape</button>'); Once we have our button element, we then need to add the shape reference, which changes the shape of the elements. To do this we will create a separate function called changeShape. While we are still in our init function, we can add an event handler to call the changeShape function onto the button. For reasons that will become apparent shortly, we will use the event delegation format of the jQuery. on() function to do this: $(this.element).on('click','button',this.changeShape); We now need to create our changeShape function; the first thing we will do is change this function name to changeShape. We will then change the function declaration to accept a parameter, in this case e. The first thing to note is that this function is called from an event listener on a DOM element and therefore this is actually the element that has been clicked on. This function was called using event delegation; the reason for this becomes apparent here as it allows us to find out which instance of the plugin belongs to the button that has been clicked on. We do this by using the e parameter that was passed to the function. The e parameter passed to the function is the jQuery event object related to the click event that has been fired. Inside it, we will find a reference to the original element that the click event was set to, which in this case is the element that the instance of the plugin is tied to. To retrieve the instance of the plugin, we can simply use the jQuery.data() function. The instance of the plugin is stored on the element as data using the data key plugin_pluginName, so we are able to retrieve it the same way as follows: var plugin = $(e.delegateTarget).data("plugin_" + pluginName); Now that we have the plugin instance, we are able to access everything it contains; the first thing we need to do is to remove the current shape class from the shape element in the DOM. To do this, we will simply find the shape element then look up in the shapes array to get the currently displayed shape, and then use the jQuery.removeClass function to remove the individual class. The code for doing this starts with a simple jQuery selector that allows us to work with the plugin element; we do this using $(plugin.element). We then look inside the plugin element to find the actual shape. As the name of the shape class is configurable, we can read this from our plugin option; so when we are finding the shape we use .find(plugin.options.shapeClass). Finally we add the class; so that we know which shape is next, we look up the shape class from the shapes array stored in the plugin options, selecting the item indicated by the plugin.shapeRef. The full command then looks as follows: $(plugin.element).find(plugin.options.shapeClass).removeClass(plugin.options.shapes[plugin.shapeRef]); We then need to work out which is the next shape we should show; we know that the current shape reference can be found in plugin.shapeRef, so we just need to work out if we have any more shapes left in the shape array or if we should start from the beginning. To do this, we look at the value of plugin.shapeRef and compare it to the length of the shapes array minus 1 (we substract 1 because arrays start at 0); if the shape reference is equal to the length of the shapes array minus 1, we know that we have reached the last shape, so we reset the plugin.shapeRef parameter to 0. Otherwise, we simply increment the shapeRef parameter by 1 as shown in the snippet: if((plugin.shapeRef) === (plugin.options.shapes.length -1)){plugin.shapeRef = 0;}else{plugin.shapeRef = plugin.shapeRef+1;} Our final step is to add the new shape class to the shape element; this can be achieved by finding the shape element and using the jQuery.addClass function to add the shape from the shapes array. This is very similar to our removeClass command that we used earlier with addClass replacing removeClass. $(plugin.element).find(plugin.options.shapeClass).addClass(plugin.options.shapes[plugin.shapeRef]); At this point we should now have a working plugin; so if we fire up the browser and navigate to the index.html file, we should get a square with a button beneath it. Clicking on the button should show the next shape. If your code is working correctly, the shapes should be shown in the order: square, circle, triangle, oval, and then loop back to square. As a final test to show that each plugin instance is tied to one element, we will add a second element to the page. This is as simple as duplicating the original shape_wrapper and creating a second one as shown: <div class="shape_wrapper"><div class="shape"></div></div> If everything is working correctly when loading the index.html page, we will have 2 squares each with a button underneath them, and on clicking the button only the shape above will change. Summary This article explained how to create your first jQuery plugin that manipulates the shape of a div element. We achieved this by writing some HTML to declare a shape and a button, declaring each shape in the CSS, and then using the JavaScript to toggle which shape is shown by toggling the CSS class appended to it. Resources for Article: Further resources on this subject: Using jQuery and jQueryUI Widget Factory plugins with RequireJS [Article] jQuery Animation: Tips and Tricks [Article] New Effects Added by jQuery UI [Article]
Read more
  • 0
  • 0
  • 1787

article-image-design-tools-and-basics
Packt
29 Aug 2013
20 min read
Save for later

Design Tools and Basics

Packt
29 Aug 2013
20 min read
(For more resources related to this topic, see here.) Owning a Makerbot 3D printer means being able to make anything you want at a push of a button, right? 3D printer owners quickly find that while 3D printers have no end of things they can produce, they also are not without their limitations. Designing an object without 3D printing in mind will result in a failed print that more resembles a bird nest or a bowl of spaghetti. Making a 3D printable object requires learning a few rules, some careful planning, and design. But once you know the rules the results can be astounding. 3D printers can even produce things with ease that traditional manufacturing cannot, for example, objects with complex internal geometry that machining cannot touch. There are many places online such as Makerbot's own Thingiverse that hosts a daily growing library of printable objects. Printing out other people's designs is all well and good for a while, but the most exciting part about 3D printing is that it can produce your designs and models. Eventually, learning how to model for 3D printing is a must. Can you learn 3D modeling? If you've ever won a round of Pictionary you've got all the artistic skill it takes to get started. If you've ever gotten past level 1 on Tetris then you've got spatial reasoning. If you've ever played with modeling clay then you know all about designing in three dimensions. Design basics There are some design rules and basic ideas that will be true regardless of the modeling software used. The working of 3D printing 3D printing has come a long way in terms of technology and cost allowing home 3D printers to be a reality. In this process there have been choices that will limit what can be printed. Seeing a 3D printer in action is the best way to learn about the process. Fortunately there are many 3D printing time lapse videos online of printers in action that can be found with a simple search. 3D printers build an object layer-by-layer from the bottom to the top. Plastic filament is heated and extruded, and each layer is built upon the last one. Usually the outside of the object is drawn and sometimes additional shells are added for strength. Then the inside is usually filled with a lattice to save plastic and provide some support for higher layers, however the inside is mostly air. This continues until the object is complete as shown in the following screenshot: Because of this layer-by-layer process, if a design is made so that any part has nothing underneath it, dangling in the air, then the printer will still extrude some plastic to try to print the part which will just dangle from the nozzle and be dragged into the next area where it will build up an ugly mess and ruin the print: Building for supportless prints One way of fixing the dangling object problem is to configure the preparing software to build the model "with supports". This means the slicer will automatically build a support lattice of plastic, up to the dangling part so that it has something to print on. Higher-end printers can actually print with a different material that can be dissolved away, but so far most home printers only use break-away supports. Either way after the print is complete it is left to the user to clean up this support material to extract the desired part. While supports do allow the creation of objects that would be impossible any other way, the supports themselves are a waste of material and often don't remove cleanly leading to a messy bottom surface where they contact the print. If a part is designed needing supports that are hard to remove, such as if they're internal and partially obscured, it can be difficult and frustrating to completely remove the support material (this can be true for even the higher-end 3D printers). The process of removing it may actually damage the print. It is possible and very easy with just the slightest application of cleverness to make designs that are printable without the need for any supports. So the blueprints in this article focus on making designs that print without supports. The limitations imposed by this demands just a little more effort but allow for the teaching of principles that are generally good to know. Designing for dual extruders Some models of Makerbot and other 3D printers have the ability to print in multiple colors at once using two different extruder heads feeding plastic from two different spools. There are some fun prints that come from this process. But as most Makerbots and other brands of home 3D printers do not have dual extruders at this time this article will not explore this process in detail. The basic idea of the process is creating two files that are aligned to print in the same space and combining them in the slicer. Designing supportless – overhangs and bridges When designing for supportless printing the rules are simple: Y prints, H prints okay, T does not print well. Branching out with overhangs It is possible to have the current layer slightly larger than the previous layer provided the overhang is not more than 45 degrees. This is because the current layer will have enough of the previous layer to stick to. Hence a shape like the capital letter Y will successfully print standing up. However, if the overhang is too great or too abrupt the new layer will droop causing a print fail, hence a shape like the capital letter T does not print. (If the T is serif and thus has downward dangling bits, it will fail even worse, as illustrated previously.) So it is important to try to keep overhangs within a 45 degree cone as they go upwards. Building bridges If a part of the print has nothing above it, but has something on either side that it can attach to, then it may be able to bridge the gap. But use caution. The printer makes no special effort in making bridges; they are drawn like any other layer: outline first, then infill. As long as the outline has something to attach to on both sides it should be fine. But if that outline is too complex or contains parts that will print in mid-air, it may not succeed. Being aware of bridges in the design and keeping them simple is the key to successful bridging. Even with a simple bridge some 3D printers need a little bit more calibration to print it well. Hence a shape like the capital letter H will successfully print most of the time. Of course this discussion is purely illustrative of the way overhangs work or fail. In real life if a Y, H, or T needed to be printed the best way to do it would be to lay them down. But for purposes of illustration it still stands that Y prints, H prints okay, T does not. Choosing a modeling tool There are many choices of modeling programs that can be used to produce 3D printable objects. There are many factors including versatility, simplicity, and cost to take into account. A tool with too steep a learning curve can turn off new users to the idea all together. A tool with too limited a set of tools can frustrate a user when they hit the limit. Investing a lot of money into something that doesn't end up going anywhere can be extremely disappointing. So it is important to explore the options. SolidWorks (www.solidworks.com) and other drafting oriented programs can do technical shapes with extreme precision. They include the necessary tools to accurately describe a shape that can be brought into the real work with high fidelity. However these sorts of tools tend to be costly and don't do artistic or organic shapes very well. Their highly technical nature also gives them a steep learning curve. OpenSCAD (www.openscad.org) is free and famous among the people who make 3D printers and can make technically accurate models as well. OpenSCAD also allows the models to be parametric, meaning that by changing a few variables and recalculating a new shape is generated. But OpenSCAD is difficult to use unless the user has a very technical and programmatic mind since the shapes are literally built from lines of code. Zbrush (pixologic.com/zbrush), Sculptris (pixologic.com/sculptris), or Wings3D (www.wings3d.com) are great tools for modeling organic shapes like the kind used in video games or animation. Sculptris and Wings3D are free and are very easy to pick up and use. But these tools lack when precision is necessary. Sketchup (www.sketchup.com) is a great free program with a library of shapes built in ready to import and play with. Its modeling tools are great for precise or architectural models. Sketchup doesn't do organic shapes well either and it can be tricky loading the plug-ins necessary for Sketchup to export their models to something printable. Even then models from Sketchup often have to go through an extensive clean up phase before they'll be ready to print. Autodesk 123D (www.123dapp.com) is not one but a whole suite of free programs designed around 3D modeling with specific focus on 3D printing. There are programs to design creatures or precise shapes. There is even an app for converting pictures of real life objects into 3D models. Some are programs that run in browser, some are downloads and some are apps for Apple devices. It's an eclectic and powerful group of programs. The Autodesk 123D suite's weakness is in its general immaturity. Autodesk is making great efforts to make modeling for 3D printing accessible for everyone but its tools still need to mature somewhat before they'll be ready to explore in depth. Blender (blender.org) is a 3D animation program that features a robust set of modeling tools. Good for artistic and organic shapes, it can also be used when precision is needed. On top all that it is free and open source, so it is still in constant development. If Blender doesn't have a particular feature it is only a matter of time until it will be added. If fact by the time this article is published chances are the version of Blender used to make it will already be out of date, but most of Blender's functionality remains unchanged version-to-version. Blender is also completely customizable so that every feature, from the key strokes used to the overall look, can be changed. The downside of Blender is that its user interface is somewhat unintuitive. This causes Blender to have a famously difficult learning curve. Because of Blender's versatility and availability it is the tool of choice for the beginning 3D designer and this work. Installing Blender This will be the first project in the article. Fortunately downloading and installing Blender is as easy as 1-2-3-4. Go to www.blender.org. Click on the Download link. Choose and download the installer for your system: Windows, Mac, or Linux, 32 bit or 64 bit. Run the installer. The installer will guide the process of loading Blender and adding icons to the system. Windows Blender.org offers installer executable and ZIP files. The zip files are for advanced users who want a portable version of Blender. When in doubt choose the executable since it will set up icons making for easy access. If in doubt whether to use the 32 or 64-bit versions picking the 32-bit will insure compatibility, but it is a good idea to find out what type of system it is being installed on as 64-bit offers significant performance improvements. Windows 7 or greater will confirm that the installer should be run. Click on Yes to assure Windows that it's okay to install Blender. Then the installer will run. The install wizard's defaults are fine for most users. Simply put the mouse over the Next button and click on every button that appears under it. On the second screen read over the Blender Terms of Service and click on I Agree to proceed. Unless you manage your installed programs directories yourself it is best to leave the defaults on the third screen as it is. Then click on Next and the install process will start. When the install process finishes leave the check box check and click on Finish to exit the installer and run Blender. Getting acquainted with Blender When Blender starts up, the Splash Screen can be dismissed by left-clicking outside the screen. The screenshots in this article use a custom color palette for print and a smaller window to minimize wasted screen space. Customizing the color palette will be discussed briefly later but these cosmetic changes will not affect the instructions presented at all. The Blender interface is broken into several different customizable panels to keep things organized. Each panel has resizing widgets in the upper-right and lower-left corners. By clicking on these widgets the panels can be split to add more panels or expanded into the territory of another to collapse panels at the user's preference. However, for now the default panels will be discussed as they provide the most common functionality for beginners. The 3D View panel The main window where things will be happening is the 3D View panel. The largest portion of the 3D view consists of the viewport where most of the work will take place. On the left-hand side of the 3D View panel is a tool bar that consists of tools relevant to the selection and mode. If the tool bar is ever not visible it can be revealed (or hidden again) by pressing Tor by clicking on the plus icon on the right-hand side that will appear when the toolbar is hidden. The specific tools in this bar will be explored as they are needed in the projects. There is another plus icon on the right that will bring up the viewport properties with properties relevant to the current selection or the viewport. This can also be revealed or hidden by pressing the Nkey. Again, the specifics will be explored further as needed. At the bottom of the 3D View panel is the 3D view menu bar with additional options followed by menus and icons related to editing and views. Hovering the mouse over each button will show what they are for. The Outliner panel The Outliner panel contains a hieratical view of all the objects in the scene. Each object can be selected by clicking on their name or the object can be hidden, locked, or excluded from rendering. Rendering means making a high quality picture from a scene for things such as animation or presentations. Doing a proper render includes setting up scene lights, cameras, textures, material properties, and many other functions that will not be explored in this article as it does not do anything that helps produce models for printing. However, exploring this functionality outside of this article can be good when trying to show off the models if printing them is not an option. The Properties panel The Properties panel is broken up into many tabs indicated by small icons. Hovering over the icons will show the name of the tab. For modeling the two tabs that will be used the most are the object and modifier tabs. Specific exploration of the tools contained therein will be done as needed. The Info panel On the top of the Blender windows is the Info panel. On the left-hand side of the Info panel there is an easy to navigate menu similar to the menu in most applications. This menu can be collapsed by clicking on the + button next to it and expanded by clicking the same. On the far right of the Info panel there is data about the current scene. If the data cannot be seen, hover the mouse over the panel, and use the middle scroll wheel or click-and-hold the middle mouse button (pressing the wheel like a button) and moving the mouse to pan the panel until the desired data is visible. The Timeline panel The Timeline panel is only relevant to doing animation and can be effectively ignored or collapsed for the purposes of this article. Because this article is only using a limited subset of Blender's functionality some things such as the Timeline panel could be customized away. However, since it is not the focus of this article to tell the reader how to customize their version of Blender, and because Blender has a much broader application, the screenshots that follow will have the Timeline panel visible. The reader is encouraged to explore Blender's other functionalities such as rendering and animation at their leisure and desire. Proper stance While all of Blender's functions are available from buttons and menus on the screen, typical Blender users rely heavily on hotkeys and shortcuts. Already the T and N keys have been discussed to bring up or collapse the Tools and Properties tabs in the 3D view. For this reason it is recommended that to use Blender have one hand on the mouse and the other hand on the keyboard at all times. This tends to be a common stance for many people but is mentioned for the few for whom learning this will be of great help. Blender customization One of Blender's strengths is its customizability. Almost every feature from the look and color, right down to the keystrokes and hotkeys are used for every action in Blender. Customization is accomplished in the Properties menu accessed from the File | User Preferences menu. The buttons across the top, switch to the various categories. Each category is packed with options. A full exploration of these options is beyond the scope of this article but the reader is encouraged to explore these options and make Blender their own. For instance if the reader is using a setup where a middle mouse button is unavailable, Blender contains an option to emulate the middle mouse button by pressing Alt along with left-click. Other systems may require other accommodations many of which are available in this menu. Setting up for Mac OSX Mac OSX users require special consideration. Blender is made for a three button mouse. If a single button mouse is all that is available, click when the instructions say Left-Mouse Button, use Alt with click for Middle-Mouse Button, and press command with click for Right-Mouse Button. General Blender tips Blender employs some conventions that are unique to its environment and as such getting acquainted with its most common quirks early can avoid frustration. First and perhaps most importantly, Ctrl+ Z for undo works in Blender will undo a multitude of mistakes. Undo in Blender remembers many past steps allowing backing up to a point before a grievous error was made. Remembering this when following along with the blueprints that follow will save the reader much frustration. Next, the location of the mouse pointer is important when using hotkeys. For example the T and N keys for the Tools and Properties tabs do not bring up those tabs if the mouse pointer is not hovering over the 3D View. If the mouse is hovering over a different panel the reaction could be unpredictable. Pressing the A key with the mouse over the 3D View will toggle selection of all objects in the scene. Pressing the A key with the mouse over the Object Tools tab will collapse the expandable menu hiding all the options of that menu. Blender uses the right-click on the mouse to select objects by default. This is perhaps the most counter intuitive thing for first time users, particularly because it will be encountered so frequently. But not everything has been swapped, just object selection. This behavior can of course be customized. If the reader would like to customize selection to the left mouse button then it is left to them to adjust the instructions accordingly. Finally, the relation of Blender units to real life units is not by default defined in Blender. Generally it is just easier to remember that 1 grid point will translate to 1 millimeter in the printed object. As the scale is increased Blender inserts darker grid lines every 10 grid lines by default which correlate to centimeters. So the default cube in the default scene would measure 2 mm on each side, which is less than 1/10 of an inch, which is very small. Suggested shortcuts In the projects in this article, when a new idea is introduced it will first be introduced with detailed steps. Once a process is taught the next time the name of the operation and the shortcut for that process will be all that is given. This does not mean that the keyboard shortcuts are the only way to do an operation but they are often the preferred method for experienced Blender users. The reader is free to accomplish the operation in any way that is comfortable for them. The blueprints This article has been designed to teach 3D printing design in a hands-on approach. A series of projects or blueprints will be presented and each one will introduce new tools and techniques. Each one builds on the last. Despite being a "virtual" process, 3D modeling has a surprisingly muscle memory aspect to it. The movements and processes need to be more than a mechanical process being executed, they need to be practiced so they can be fluid and eventually seamless. To that end the reader is advised not to skip any of the blueprints and follow along actually doing each one. The objects being designed in this article are, most of them, very small so that they can be printed without taking too much time or producing too much waste. The reader can make larger versions if they like but that is left for their own challenge activities. Summary 3D printing is cool. Learning to design your own models is the best way to take full advantage of 3D printing today. This article will teach 3D modeling by a series of hands-on activities so it's a good idea not to skip and actually follow along with each blueprint. While home 3D printers have the capability to do break away supports these are messy and wasteful. It is possible to design things to be able to print without the need of any supports. When designing things for support-less 3D prints remember Y prints, H prints okay, T does not print. Keep outward inclines gradual and no more than 45 degrees to be safe. There are many 3D modeling programs to choose from. Some are expensive, some are free. Some are better for technical works, others do artistic or organic shapes better. Some are easy to learn, some take more practice. This article will use Blender since it is free and open source, has tools for modeling technical and organic shapes and is not too difficult to learn if you learn by doing. Blender can be a bit tricky to get started with since it employs some conventions unique to its environment. Blender can be customized but this article will stick with the defaults so everyone is on the same page. Generally remember that Ctrl+ Z undoes a multiple mistakes and can get Blender back to the state it was before, useful in tutorials to get back on track. The location of the mouse pointer is important when using Blender's hotkeys, which is the best way to learn to use Blender. Blender uses the right-click on mouse for selection by default. Finally, Blender's units translate to real life by 1 Blender grid space = 1 millimeter. Resources for Article: Further resources on this subject: Building Your First Bean in ColdFusion [Article] Designer Friendly Templates [Article] The Trivadis Integration Architecture Blueprint [Article]
Read more
  • 0
  • 0
  • 9734

article-image-customization
Packt
29 Aug 2013
18 min read
Save for later

Customization

Packt
29 Aug 2013
18 min read
(For more resources related to this topic, see here.) Now that you've got a working multisite installation, we can start to add some customizations. Customizations can come in a few different forms. You're probably aware of the customizations that can be made via WordPress plugins and custom WordPress themes. Another way we can customize a multisite installation is by creating a landing page that displays information about each blog in the multisite network, as well as displaying information about the author for that individual blog. I wrote a blog post shortly after WordPress 3.0 came out detailing how to set this landing page up. At the time, I was working for a local newspaper and we were setting up a blog network for some of our reporters to blog about politics (being in Iowa, politics are a pretty big deal here, especially around Caucus time). You can find the post at http://www.longren.org/how-to-wordpress-3-0-multi-site-blog-directory/ if you'd like to read it. There's also a blog-directory.zip file attached to the post that you can download and use as a starting point. Before we get into creating the landing page, let's get the really simple stuff out of the way and briefly go over how themes and plugins are managed in WordPress multisite installations. We'll start with themes. Themes can be activated network-wide, which is really nice if you have a theme that you want every site in your blog network to use. You can also activate a theme for an individual blog, instead of activating the theme for the entire network. This is helpful if one or two individual blogs need to have a totally unique theme that you don't want to be available to the other blogs. Theme management You can install themes on a multisite installation the same way you would with a regular WordPress install. Just upload the theme folder to your wp-content/themes folder to install the theme. Installing a theme is only part of the process for individual blogs to use the themes; you'll need to activate them for the entire blog network or for specific blogs. To activate a theme for an entire network, click on Themes and then click on Installed Themes in the Network Admin dashboard. Check the themes that you want to enable, select Network Enable in the Bulk Actions drop-down menu, and then click on the Apply button. That's all there is to activating a theme (or multiple themes) for an entire multisite network. The individual blog owners can apply the theme just as you would in a regular, nonmultisite WordPress installation. To activate a theme for just one specific blog and not the entire network, locate the target blog using the Sites menu option in the Network Admin dashboard. After you've found it, put your mouse cursor over the blog URL or domain. You should see the action menu appear immediately under the blog URL or domain. The action menu includes options such as Edit, Dashboard, and Deactivate. Click on the Edit action menu item and then navigate to the Themes tab. To activate an individual theme, just click on Enable below the theme that you want to activate. Or, if you want to activate multiple themes for the blog, check all the themes you want through the checkboxes on the left-hand side of each theme from the list, select Enable in the Bulk Actions drop-down menu, and then click on the Apply button. An important thing to keep in mind is that themes that have been activated for the entire network won't be shown here. Now the blog administrator can apply the theme to their blog just as they normally would. Plugin management To install a plugin for network use, upload the plugin folder to wp-content/plugins/ as you normally would. Unlike themes, plugins cannot be activated on a per-site basis. As network administrator, you can add a plugin to the Plugins page for all sites, but you can't make a plugin available to one specific site. It's all or nothing. You'll also want to make sure that you've enabled the Plugins page for the sites that need it. You can enable the Plugins page by visiting the Network Admin dashboard and then navigating to the Network Settings page. At the bottom of that page you should see a Menu Settings section where you can check a box next to Plugins to enable the plugins page. Make sure to click on the Save Changes button at the bottom or nothing will change. You can see the Menu Settings section in the following screenshot. That's where you'll want to enable the Plugins page. Enabling the Plugins page After you've ensured that the Plugins page is enabled, specific site administrators will be able to enable or disable plugins as they normally would. To enable a plugin for the entire network go to the Network Admin dashboard, mouse over the Plugins menu item, and then click on Installed Plugins. This will look pretty familiar to you; it looks pretty much like the Installed Plugins page does on a typical WordPress single-site installation. The following screenshot shows the installed Plugins page: Enable plugins for the entire network You'll notice below each plugin there's some text that reads Network Activate. I bet you can guess what clicking that will do. Yes, clicking on the Network Activate link will activate that plugin for the entire network. That's all there is to the basic plugin setup in WordPress multisite. There's another plugin feature that is often overlooked in WordPress multisite, and that's must-use plugins. These are plugins that are required for every blog or site on the network. Must-use plugins can be installed in the wp-content/mu-plugins/ folder but they must be single-file plugins. The files within folders won't be read. You can't deactivate or activate the must-use plugins. If they exist in the mu-plugins folder, they're used. They're entirely hidden from the Plugin pages, so individual site administrators won't even see them or know they're there. I don't think must-use plugins are a commonly used thing, but it's nice information to have just in case. Some plugins, especially domain mapping plugins, need to be installed in mu-plugins and need to be activated before the normal plugins. Third-party plugins and plugins for plugin management We should also discuss some of the plugins that are available for making the management of plugins and themes on WordPress multisite installations a bit easier. One of the most popular plugins is called Multisite Plugin Manager, and is developed by Aaron Edwards of UglyRobot.com. The Multisite Plugin Manager plugin was previously known as WPMU Plugin Manager. The plugin can be obtained from the WordPress Plugin Directory at http://wordpress.org/plugins/multisite-plugin-manager/. Here's a quick rundown of some of the plugin features: Select which plugins specific sites have access to Set certain plugins to autoactivate itself for new blogs or sites Activate/deactivate a plugin on all network sites Assign some special plugin access permissions to specific network sites Another plugin that you may find useful is called WordPress MU Domain Mapping. It allows you to easily map any blog or site to an external domain. You can find this plugin in the WordPress Plugin Directory at http://wordpress.org/plugins/wordpress-mu-domain-mapping/. There's one other plugin I want to mention; the only drawback is that it's not a free plugin. It's called WP Multisite Replicator, and you can probably guess what it does. This plugin will allow you to set up a "template" blog or site and then replicate that site when adding new sites or blogs. The idea is that you'd create a blog or site that has all the features that other sites in your network will need. Then, you can easily replicate that site when creating a new site or blog. It will copy widgets, themes, and plugin settings to the new site or blog, which makes deploying new, identical sites extremely easy. It's not an expensive plugin, costing about $36 at the moment of writing, which is well worth it in my opinion if you're going to be creating lots of sites that have the same basic feature set. WP Multisite Replicator can be found at http://wpebooks.com/replicator/. Creating a blog directory / landing page Now that we've got the basic theme and plugin stuff taken care of, I think it's time to move onto creating a blog directory or a landing page, whichever you prefer to call it. From this point on I'll be referring to it as a blog directory. You can see a basic version of what we're going to make in the following screenshot. The users on my example multisite installation, at http://multisite.longren.org/, are Kayla and Sydney, my wife and daughter. Blog directory example As I mentioned earlier in this article, I wrote a post about creating this blog directory back when WordPress 3.0 was first released in 2010. I'll be using that post as the basis for most of what we'll do to create the blog directory with some things changed around, so this will integrate more nicely into whatever theme you're using on the main network site. The first thing we need to do is to create a basic WordPress page template that we can apply to a newly created WordPress page. This template will contain the HTML structure for the blog directory and will dictate where the blog names will be shown and where the recent posts and blog description will be displayed. There's no reason that you need to stick with the following blog directory template specifically. You can take the code and add or remove various elements, such as the recent post if you don't want to show them. You'll want to implement this blog directory template as a child theme in WordPress. To do that, just make a new folder in wp-content/themes/. I typically name my child theme folders after their parent themes. So, the child theme folder I made was wp-content/themes/twentythirteen-tyler/. Once you've got the child theme folder created, make a new file called style.css and make sure it has the following code at the top: /*Theme Name: Twenty Thirteen Child ThemeTheme URI: http://yourdomain.comDescription: Child theme for the Twenty Thirteen themeAuthor: Your name hereAuthor URI: http://example.com/about/Template: twentythirteenVersion: 0.1.0*//* ================ *//* = The 1Kb Grid = */ /* 12 columns, 60 pixels each, with 20pixel gutter *//* ================ */.grid_1 { width:60px; }.grid_2 { width:140px; }.grid_3 { width:220px; }.grid_4 { width:300px; }.grid_5 { width:380px; }.grid_6 { width:460px; }.grid_7 { width:540px; }.grid_8 { width:620px; }.grid_9 { width:700px; }.grid_10 { width:780px; }.grid_11 { width:860px; }.grid_12 { width:940px; }.column {margin: 0 10px;overflow: hidden;float: left;display: inline;}.row {width: 960px;margin: 0 auto;overflow: hidden;}.row .row {margin: 0 -10px;width: auto;display: inline-block;}.author_bio {border: 1px solid #e7e7e7;margin-top: 10px;padding-top: 10px;background:#ffffff url('images/sign.png') no-repeat right bottom;z-index: -99999;}small { font-size: 12px; }.post_count {text-align: center;font-size: 10px;font-weight: bold;line-height: 15px;text-transform: uppercase;float: right;margin-top: -65px;margin-right: 20px;}.post_count a {color: #000;}#content a {text-decoration: none;-webkit-transition: text-shadow .1s linear;outline: none;}#content a:hover {color: #2DADDA;text-shadow: 0 0 6px #278EB3;} The preceding code adds the styling to your child theme, and also tells WordPress the name of your child theme. You can set a custom theme name if you want by changing the Theme Name line to whatever you like. The only fields in that big comment block that are required are the Theme Name and Template. Template, which should be set to whatever the parent theme's folder name is. Now create another file in your child theme folder and name it blog-directory.php. The remaining blocks of code need to go into that blog-directory.php file: <?php/*** Template Name: Blog Directory** A custom page template with a sidebar.* Selectable from a dropdown menu on the add/edit page screen.** @package WordPress* @subpackage Twenty Thirteen*/?><?php get_header(); ?><div id="container" class="onecolumn"><div id="content" role="main"><?php the_post(); ?><div id="post-<?php the_ID(); ?>" <?php post_class(); ?>><?php if ( is_front_page() ) { ?><h2 class="entry-title"><?php the_title(); ?></h2><?php } else { ?><h1 class="entry-title"><?php the_title(); ?></h1><?php } ?><div class="entry-content"><!-- start blog directory --><?php// Get the authors from the database ordered randomlyglobal $wpdb;$query = "SELECT ID, user_nicename from $wpdb->users WHERE ID != '1'ORDER BY 1 LIMIT 50";$author_ids = $wpdb->get_results($query);// Loop through each authorforeach($author_ids as $author) {// Get user data$curauth = get_userdata($author->ID);// Get link to author page$user_link = get_author_posts_url($curauth->ID);// Get blog details for the authors primary blog ID$blog_details = get_blog_details($curauth->primary_blog);$postText = "posts";if ($blog_details->post_count == "1") {$postText = "post";}$updatedOn = strftime("%m/%d/%Y at %l:%M %p",strtotime($blog_details->last_updated));if ($blog_details->post_count == "") {$blog_details->post_count = "0";}$posts = $wpdb->get_col( "SELECT ID FROM wp_".$curauth->primary_blog."_posts WHERE post_status='publish' AND post_type='post' ANDpost_author='$author->ID' ORDER BY ID DESC LIMIT 5");$postHTML = "";$i=0;foreach($posts as $p) {$postdetail=get_blog_post($curauth->primary_blog,$p);if ($i==0) {$updatedOn = strftime("%m/%d/%Y at %l:%M %p",strtotime($postdetail->post_date));}$postHTML .= "&#149; <a href="$postdetail->guid">$postdetail->post_title</a><br />";$i++;}?> The preceding code sets up the theme and queries the WordPress database for authors. In WordPress multisite, users who have the Author permission type have a blog on the network. There's also code for grabbing posts from each of the network sites for displaying the recent posts from them: <div class="author_bio"><div class="row"><div class="column grid_2"><a href="<?php echo $blog_details->siteurl; ?>"><?php echo get_avatar($curauth->user_email, '96','http://www.gravatar.com/avatar/ad516503a11cd5ca435acc9bb6523536'); ?></a></div><div class="column grid_6"><a href="<?php echo $blog_details->siteurl; ?>" title="<?php echo$curauth->display_name; ?> - <?=$blog_details->blogname?>"><?php //echo $curauth->display_name; ?> <?=$curauth->display_name;?></a><br /><small><strong>Updated <?=$updatedOn?></strong></small><br /><?php echo $curauth->description; ?></div><div class="column grid_3"><h3>Recent Posts</h3><?=$postHTML?></div></div><span class="post_count"><a href="<?php echo $blog_details->siteurl;?>" title="<?php echo $curauth->display_name; ?>"><?=$blog_details->post_count?><br /><?=$postText?></a></span></div><?php } ?><!-- end blog directory --><?php wp_link_pages( array( 'before' => '<div class="page-link">' .__( 'Pages:', 'twentythirteen' ), 'after' => '</div>' ) ); ?><?php edit_post_link( __( 'Edit', 'twentythirteen' ), '<spanclass="edit-link">', '</span>' ); ?></div><!-- .entry-content --></div><!-- #post-<?php the_ID(); ?> --><?php comments_template( '', true ); ?></div><!-- #content --></div><!-- #container --><?php //get_sidebar(); ?><?php get_footer(); ?> Once you've got your blog-directory.php template file created, we can get actually started by setting up the page to serve as our blog directory. You'll need to set the root site's theme to your child theme; do it just as you would on a nonmultisite WordPress installation. Before we go further, let's create a couple of network sites so we have something to see on our blog directory. Go to the Network Admin dashboard, mouse over the Sites menu option in the left-hand side menu, and then click on Add New. If you're using a directory network type, as I am, the value you enter for the Site Address field will be the path to the directory that site sits in. So, if you enter tyler as the Site Address value, that the site can be reached at http://multisite.longren.org/tyler/. The settings that I used to set up multisite.longren.org/tyler/ can be seen in the following screenshot. You'll probably want to add a couple of sites just so you get a good idea of what your blog directory page will look like. Example individual site setup Now we can set up the actual blog directory page. On the main dashboard (that is, /wp-admin/index.php), mouse over the Pages menu item on the left-hand side of the page and then click on Add New to create a new page. I usually name this page Home, as I use the blog directory as the first page that visitors see when visiting the site. From there, visitors can choose which blog they want to visit and are also shown a list of the most recent posts from each blog. There's no need to enter any content on the page, unless you want to. The important part is selecting the Blog Directory template. Before you publish your new Home / blog directory page, make sure that you select Blog Directory as the Template value in the Page Attributes section. An example a Home / blog directory page can be seen in the following screenshot: Example Home / blog directory page setup Once you've got your page looking like the example, as shown in the previous screenshot, you can go ahead and publish that page. The Update button in the previous screenshot will say Publish if you've not yet published the page. Next you'll want to set the newly created Home / blog directory page as the front page for the site. To do this, mouse over the Settings menu option on the left-hand side of the page and then click on Reading. For the Front page displays value, check A static page (select below). Previously, Your latest posts was checked. Then for the Front Page drop-down menu, just select the Home page that we just created and click on the Save Changes button at the bottom of the page. I usually don't set anything for the Posts page drop-down menu because I never post to the "parent" site. If you do intend to make posts on the parent site, I'd suggest that you create a new blank page titled Posts and then select that page as your Posts page. The reading settings I use at multisite.longren.org can be as shown in the following screenshot: Reading settings setup After you've saved your reading settings, open up your parent site in your browser and you should see something similar to what I showed in the Blog directory example screenshot. Again, there's no need for you to keep the exact setup that I've used in the example blog-directory.php file. You can give that any style/design that you want. You can rearrange the various pieces on the page as you prefer. You should probably have a decent working knowledge of HTML and CSS to accomplish this, however. You should have a basic blog directory at this point. If you have any experience with PHP, HTML, and CSS, you can probably extend this basic code and do a whole lot more with it. The number of plugins is astounding and they are of very good quality, generally. And I think Automattic has done great things for WordPress in general. No other CMS can claim to have anything like the number of plugins that WordPress does. Summary You should be able to effectively manage themes and plugins in a multisite installation now. If you set the code up, you've got a directory showcasing network member content and, more importantly, know how to set up and customize a WordPress child theme now. Resources for Article : Further resources on this subject: Customization using ADF Meta Data Services [Article] Overview of Microsoft Dynamics CRM 2011 [Article] Customizing an Avatar in Flash Multiplayer Virtual Worlds [Article]
Read more
  • 0
  • 0
  • 2700

article-image-storytelling
Packt
28 Aug 2013
14 min read
Save for later

Storytelling

Packt
28 Aug 2013
14 min read
(For more resources related to this topic, see here.) Adding words to a sprite One of the first things we need to know to tell a story using Scratch is to display words on the screen to convey the story. Getting ready Start off by importing a new sprite (unless you like the default) as well as a background you like. Also, start thinking about a story you want to tell—or you can just follow what we do here! This family of blocks are the say and think blocks: So what's the difference between all of these blocks? Two of these blocks help with timing. These are the first and third in the picture that include a time condition. These are the ones we will focus on because we generally want to control how long the words are displayed on the screen. The story we are going to make here is going to be told by Monkey Mike. We labeled our sprite this to make understanding the logic of the programming a bit easier. Now we're ready to get building a story! How to do it... Follow these steps to get going: Drag over the block with the green flag that we used to start our programs from the Events category. We'll start our story by clicking on the green flag on the stage. Still using the older version of Scratch (Scratch 1.4)? All of the blocks in the Events category can be found in the Control category. This new category was added with the new version of Scratch. Next, we're going to return to the Looks block category and drag over the think block, the first one including the timing. Enter Hmm…I guess I'll start telling a story. into the text block. Click on the green flag and test the program. You should see a thought bubble pop up as if your sprite is thinking. It should be similar to the following screenshot, depending of course on the background and sprite you chose: You may wish to adjust the number of seconds for which the thought bubble appears. You do this by changing the number associated with the think block in the code. Enter the number of seconds it shows for how long you expect your viewer to need to read the text. The same rule applies for other texts being displayed. Now, we can drag in our next block—the say block—again including the timing element. You might be wondering what is the difference between the say and think blocks. Both accomplish similar goals. You can think of them as cartoons. The think block imitates the thoughts of the character while the say block suggests that the character is saying something. Note that neither makes the character make a noise. Enter the text in this block as Hi, my name is Monkey Mike. We can continue creating a basic story by adding more and more of these blocks to our code. If you want to end your story with the text remaining on the screen, just use the say or think block without the timing element. This will keep the text on the screen until the viewer either starts the program over or does something else to trigger it (we'll learn more about this option later). How it works... So far, this program is relatively simple. Our code so far is: We can see this sequence of code starting off with the green flag being clicked. Following that, our sprite thinks about starting the story, and then he begins. Naturally, your program may vary depending on how much you've digressed from the story we are using here. See also For more information about timing your story, particularly with multiple sprites in the story, see the next recipe, Adjusting the timing Adjusting the timing There is a good chance that the story you have in mind includes more than one sprite. This means that you are also going to need to think about timing in your story since you don't want to have both sprites talking at the same time. Timing can become more and more complex depending on the program, especially as you add more and more sprites and length to your story. A good way to handle this situation is to think ahead of time as to when you want your sprite to speak, and when you want them to simply observe. Having this planned out will help you program much more quickly. Getting ready Continuing with our existing story, add another sprite. For example, we added a frog to our program in the bottom center. Copy over the same code (that we used for the first sprite) to make the second sprite think and talk. Note that if you duplicated the sprite, this is done for you. You'll notice both of them talking at the same time, which is what we are going to learn to fix (see the following screenshot showing roughly what you should see). Our example is relatively simple, but you can apply this concept to even the most complicated Scratch programs. Remember, you don't need to recreate the code for the new sprite. With the original sprite selected, click and drag all of the code (beginning with the top hat block) on top of the picture icon of the sprite located below the stage. Your code should then appear in the script area of both sprites. This is what you should see when you run your program: How to do it... Our next step is to get the timing right, and then we'll worry about making our characters say something different from each other. Follow these steps: For our story, we want Monkey Mike to start things off and have Frog follow. We know that Monkey Mike thinks for two seconds, so there needs to be a delay of at least two seconds on what Frog thinks. Notice that in the Control blocks we have a block called wait 1 secs with the 1 being an input box for you to change the number. While working in the script area for Frog, drag over the wait block and place it directly underneath the block with the green flag, as shown in the following screenshot: Next, change the value in the block you just dragged over to 2 instead of 1. Now, we'll want to add another wait block in between the think and say blocks we have for Frog. Make this block 2 seconds long as well. If you run your program now, you'll still notice a bit of a problem. We still need to make Monkey Mike wait while Frog is talking. Return to the script area for Monkey Mike. Place a wait block in between the think and say blocks, just as we did for Frog. Change this value to 2 as well. Now, change the text of Frog's thought bubble to I wonder if Monkey Mike notices me down here. Then, change the say block to Hi, you can just call me Frog. Run your program and see what happens. It should flow much better now that we've adjusted the timing. How it works... So now you're probably wondering what is happening behind the scenes. Let's look at the two pieces of code. Our code for Monkey Mike is shown here: And here is the code for Frog: The biggest thing to notice in thinking about how the script runs in our program is that since both scripts begin with the block with the green flag, both scripts start simultaneously. In essence, you can have an unlimited number of scripts running simultaneously in Scratch. We'll learn soon how to get different scripts started with other Events blocks. This will give us much more control over our programs. While we may have made it appear—when watching the story—that the sprites are waiting for each other, really what is happening is that each script is playing independently of the other. We just adjusted the timing effectively to give the story the timing we want. There's more... Maybe you don't want to have to click on the green flag to start the story. An alternative is to use the when key pressed top hat block instead, also from the Events category: If you replace the green flag block with this new block, your story will start by pressing a specific key on the keyboard. By default, the block is triggered by the Space bar. You can change this by clicking on the black down arrow located next to the word space. You'll see that this is the block we will use quite frequently (to get different aspects of our program to start) when we get into creating games and other programs. For now, we'll stick with using the standard green-flag block for most script starting, but think of this as a good alternative in your own programming. See also For more details on timing, see the Adding words to a sprite recipe To see how to get your sprites to interact, take a look at our next recipe, Sprites interacting with other sprites Later in this article in the Basic broadcasting and receiving recipe, we'll explore a fun way to get background communication in your program Sprites interacting with other sprites When making your story, there is a good chance you will want to get movement on the stage so your story is a bit more exciting. This recipe focuses on how to have sprites react when they are touching or moving around other sprites. Getting ready For this recipe, we're going to continue working with the story we built in our previous recipes of this article. Our goal for this recipe is to get Frog to move across the screen and react to Monkey Mike when they touch. How to do it... Let's get started: To begin the movement of Frog, the user will have to click on the sprite. We'll need to provide directions to the user in order to accomplish this. At the end of Frog's dialogue (from before), add another say block and give it the text Click me to get me moving. Now we'll introduce a new top hat block. This is the when this sprite clicked block, located under the Events blocks category. It changes based on the sprite you are working on, so for ours it should indicate you are working with Frog. We'll drag this block over and begin a new script in the script area.. Drag over a forever loop from the Control blocks underneath our new top hat block. Place a move 10 steps block (from Motion) and the if on edge, bounce block (also from Motion) into the forever loop. Change the number of steps to something low, such as the number 2, to make sure the sprite moves slowly. Select the second orientation option in the 3-button option area of the sprite settings, as shown in the following screenshot. First we have to click on the settings option: And then: Now, if we run our program and click on Frog on the stage, we'll see Frog move slowly back and forth across the stage. Our next step will be to have the sprites interact when they touch. We want Monkey Mike to react when Frog comes in front of him. In order to do this, we'll need to head over to the Sensing category of blocks. We'll also need a new Control block. Change the sprite we are working with to be Monkey Mike. Underneath the dialog of Monkey Mike, drag over the forever block. This block is going to be triggered by a new sensing block. Into the loop you created in step 9, drag an if () then block. If you are working in Scratch 1.4, steps 9 and 10 can be combined by using the forever if block. This block was eliminated in the new version of Scratch. Drag over the touching block inside the look you just created, as shown in the following screenshot: Change the touching block by clicking on the black drop-down arrow and selecting Frog. You can use the touching block to sense when your sprite is touching any other sprite, or the mouse-pointer, or an edge. This will be very useful when we get into more advanced topics. Now we need to make Monkey Mike say something when he is "touched" by Frog. Drag in the say block (with time element) and drop it within the forever block. Change the text to say Hey Frog, don't block my view. Now run your program to give it a test! Frog will pass in front of Monkey Mike and Monkey Mike will state his observation that Frog is in his way. This will continue as long as you let it go. How it works... As in our previous recipes, we have several scripts—all running at once. We learned about a new block, the when this sprite clicked block. This block is similar to our other top hat blocks in that it starts off a script. You can always use this block to start something when you want that particular sprite to be clicked. This only applies to the specific sprite you are programming though, so if you want to click on Frog and have something happen to Monkey Mike, you'll have to use a workaround (we'll talk about this in the next recipe). Now let's take a look at the script for Monkey Mike. You should have something like the following screenshot: Once Monkey Mike finishes his dialog at the start of the story, he waits for Frog to pass by his field of vision. This block is essentially a combination of two other Control blocks available to us, so saves us time in terms of coding. We also have, available for use, the forever loop, which we've used before. Secondly, there is the if block. Any block with an if embedded creates an if statement, which is triggered when the statement is true. Our combined block that we used makes Monkey Mike constantly look for that statement to be true, and then repeats the code inside until the story is manually stopped. If you are extending the story and still want Monkey Mike to say something about Frog passing by, you'll have to create a separate script to handle the forever if loop. This method of creating the code works well when you want nothing else added. However, now you can't add more talking after the loop. Also note that if your Frog isn't large enough, or close enough to the monkey, part of this code will never need to run. There's more... Perhaps we don't want Monkey Mike to comment on Frog passing by for the entire story—after all, there is a good chance this will affect how your story flows. We also have the option of using another block combination as an alternative. Here, we see that we can integrate the repeat loop and the if loop to create a loop that looks for the trigger a certain number of times—in our case 10. You can change this number if you want to something lower or something higher. The logic of this section of code isn't too complicated. We see that the repeat loop continues what is inside it, 10 times. In other words, our code will check the condition we set (that is, whether or not we are touching Frog) 10 times, and then will stop checking and move on to whatever else we tack onto this script. See also To see more ways for sprites to interact, check out the next recipe, Basic broadcasting and receiving. This recipe will teach you a lot about basic techniques of background communication that we'll need to use in future projects.
Read more
  • 0
  • 0
  • 1691
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-introduction-ai
Packt
28 Aug 2013
30 min read
Save for later

Introduction to AI

Packt
28 Aug 2013
30 min read
(For more resources related to this topic, see here.) Artificial Intelligence (AI) Living organisms such as animals and humans have some sort of intelligence that helps us in making a particular decision to perform something. On the other hand, computers are just electronic devices that can accept data, perform logical and mathematical operations at high speeds, and output the results. So, Artificial Intelligence (AI) is essentially the subject of making computers able to think and decide like living organisms to perform specific operations. So, apparently this is a huge subject. But it is really important to understand the basics of AI being used in different domains. AI is just a general term; its implementations and applications are different for different purposes, solving different sets of problems. Before we move on to game-specific techniques, we'll take a look at the following research areas in AI applications: Computer vision: It is the ability to take visual input from sources such as videos and cameras, and analyze them to do particular operations such as facial recognition, object recognition, and optical-character recognition. Natural language processing (NLP): It is the ability that allows a machine to read and understand the languages, as we normally write and speak. The problem is that the languages we use today are difficult for machines to understand. There are many different ways to say the same thing, and the same sentence can have different meanings according to the context. NLP is an important step for machines, since they need to understand the languages and expressions we use, before they can process them and respond accordingly. Fortunately, there's an enormous amount of data sets available on the Web that can help researchers to do automatic analysis of a language. Common sense reasoning: This is a technique that our brains can easily use to draw answers even from the domains we don't fully understand. Common sense knowledge is a usual and common way for us to attempt certain questions, since our brains can mix and interplay between the context, background knowledge, and language proficiency. But making machines to apply such knowledge is very complex, and still a major challenge for researchers. AI in games Game AI needs to complement the quality of a game. For that we need to understand the fundamental requirement that every game must have. The answer should be easy. It is the fun factor. So, what makes a game fun to play? This is the subject of game design, and a good reference is The Art of Game Design by Jesse Schell. Let's attempt to tackle this question without going deep into game design topics. We'll find that a challenging game is indeed fun to play. Let me repeat: it's about making a game challenging. This means the game should not be so difficult that it's impossible for the player to beat the opponent, or too easy to win. Finding the right challenge level is the key to make a game fun to play. And that's where the AI kicks in. The role of AI in games is to make it fun by providing challenging opponents to compete, and interesting non-player characters (NPCs) that behave realistically inside the game world. So, the objective here is not to replicate the whole thought process of humans or animals, but to make the NPCs seem intelligent by reacting to the changing situations inside the game world in a way that makes sense to the player. The reason that we don't want to make the AI system in games so computationally expensive is that the processing power required for AI calculations needs to be shared between other operations such as graphic rendering and physics simulation. Also, don't forget that they are all happening in real time, and it's also really important to achieve a steady framerate throughout the game. There were even attempts to create dedicated processor for AI calculations (AI Seek's Intia Processor). With the ever-increasing processing power, we now have more and more room for AI calculations. However, like all the other disciplines in game development, optimizing AI calculations remains a huge challenge for the AI developers. AI techniques In this section, we'll walk through some of the AI techniques being used in different types of games. So, let's just take it as a crash course, before actually going into implementation. If you want to learn more about AI for games, there are some really great books out there, such as Programming Game AI by Example by Mat Buckland and Artificial Intelligence for Games by Ian Millington and John Funge. The AI Game Programming Wisdom series also contain a lot of useful resources and articles on the latest AI techniques. Finite State Machines (FSM) Finite State Machines (FSM) can be considered as one of the simplest AI model form, and are commonly used in the majority of games. A state machine basically consists of a finite number of states that are connected in a graph by the transitions between them. A game entity starts with an initial state, and then looks out for the events and rules that will trigger a transition to another state. A game entity can only be in exactly one state at any given time. For example, let's take a look at an AI guard character in a typical shooting game. Its states could be as simple as patrolling, chasing, and shooting. Simple FSM of an AI guard character There are basically four components in a simple FSM: States: This component defines a set of states that a game entity or an NPC can choose from (patrol, chase, and shoot) Transitions: This component defines relations between different states Rules: This component is used to trigger a state transition (player on sight, close enough to attack, and lost/killed player) Events: This is the component, which will trigger to check the rules (guard's visible area, distance with the player, and so on) So, a monster in Quake 2 might have the following states: standing, walking, running, dodging, attacking, idle, and searching. FSMs are widely used in game AI especially, because they are really easy to implement and more than enough for both simple and somewhat complex games. Using simple if/else statements or switch statements, we can easily implement an FSM. It can get messy, as we start to have more states and more transitions. Random and probability in AI Imagine an enemy bot in an FPS game that can always kill the player with a headshot, an opponent in a racing game that always chooses the best route, and overtakes without collision with any obstacle. Such a level of intelligence will make the game so difficult that it becomes almost impossible to win. On the other hand, imagine an AI enemy that always chooses the same route to follow, or tries to escape from the player. AI controlled entities behaving the same way every time the player encounters them, makes the game predictable and easy to win. Both of the previous situations obviously affect the fun aspect of the game, and make the player feel like the game is not challenging or fair enough anymore. One way to fix this sort of perfect AI and stupid AI is to introduce some errors in their intelligence. In games, randomness and probabilities are applied in the decision making process of AI calculations. The following are the main situations when we would want to let our AI entities change a random decision: Non-intentional: This situation is sometimes a game agent, or perhaps an NPC might need to make a decision randomly, just because it doesn't have enough information to make a perfect decision, and/or it doesn't really matter what decision it makes. Simply making a decision randomly and hoping for the best result is the way to go in such a situation. Intentional: This situation is for perfect AI and stupid AI. As we discussed in the previous examples, we will need to add some randomness purposely, just to make them more realistic, and also to match the difficulty level that the player is comfortable with. Such randomness and probability could be used for things such as hit probabilities, plus or minus random damage on top of base damage. Using randomness and probability we can add a sense of realistic uncertainty to our game and make our AI system somewhat unpredictable. We can also use probability to define different classes of AI characters. Let's look at the hero characters from Defense of the Ancient (DotA), which is a popular action real-time strategy (RTS) game mode of Warcraft III. There are three categories of heroes based on the three main attributes: strength, intelligence, and agility. Strength is the measure of the physical power of the hero, while intellect relates to how well the hero can control spells and magic. Agility defines a hero's ability to avoid attacks and attack quickly. An AI hero from the strength category will have the ability to do more damage during close combat, while an intelligence hero will have more chance of success to score higher damage using spells and magic. Carefully balancing the randomness and probability between different classes and heroes, makes the game a lot more challenging, and makes DotA a lot fun to play. The sensor system Our AI characters need to know about their surroundings, and the world they are interacting with, in order to make a particular decision. Such information could be as follows: Position of the player: This information is used to decide whether to attack or chase, or keep patrolling Buildings and objects nearby: This information is used to hide or take cover Player's health and its own health: This remaining information is used to decide whether to retreat or advance Location of resources on the map in an RTS game: This information is used to occupy and collect resources, required for constructing and producing other units As you can see, it could vary a lot depending on the type of game we are trying to build. So, how do we collect that information? Polling One method to collect such information is polling. We can simply do if/else or switch checks in the FixedUpdate method of our AI character. AI character just polls the information they are interested in from the game world, does the checks, and takes action accordingly. Polling methods works great, if there aren't too many things to check. However, some characters might not need to poll the world states every frame. Different characters might require different polling rates. So, usually in larger games with more complex AI systems, we need to deploy an event-driven method using a global messaging system. The messaging system AI does decision making in response to the events in the world. The events are communicated between the AI entity and the player, the world, or the other AI entities through a messaging system. For example, when the player attacks an enemy unit from a group of patrol guards, the other AI units need to know about this incident as well, so that they can start searching for and attacking the player. If we were using the polling method, our AI entities will need to check the state of all the other AI entities, in order to know about this incident. But with an event-driven messaging system, we can implement this in a more manageable and scalable way. The AI characters interested in a particular event can be registered as listeners, and if that event happens, our messaging system will broadcast to all listeners. The AI entities can then proceed to take appropriate actions, or perform further checks. The event-driven system does not necessarily provide faster mechanism than polling. But it provides a convenient, central checking system that senses the world and informs the interested AI agents, rather than each individual agent having to check the same event in every frame. In reality, both polling and messaging system are used together most of the time. For example, AI might poll for more detailed information when it receives an event from the messaging system. Flocking, swarming, and herding Many living beings such as birds, fish, insects, and land animals perform certain operations such as moving, hunting, and foraging in groups. They stay and hunt in groups, because it makes them stronger and safer from predators than pursuing goals individually. So, let's say you want a group of birds flocking, swarming around in the sky; it'll cost too much time and effort for animators to design the movement and animations of each bird. But if we apply some simple rules for each bird to follow, we can achieve emergent intelligence of the whole group with complex, global behavior. One pioneer of this concept is Craig Reynolds, who presented such a flocking algorithm in his SIGGRAPH paper, 1987, Flocks, Herds and Schools – A Distributed Behavioral Model. He coined the term "boid" that sounds like "bird", but referring to a "bird-like" object. He proposed three simple rules to apply to each unit, which are as follows: Separation: This rule is used to maintain a minimum distance with neighboring boids to avoid hitting them Alignment: This rule is used to align itself with the average direction of its neighbors, and then move in the same velocity with them as a flock Cohesion: This step is used to maintain a minimum distance with the group's center of mass These three simple rules are all that we need to implement a realistic and a fairly complex flocking behavior for birds. They can also be applied to group behaviors of any other entity type with little or no modifications. Path following and steering Sometimes we want our AI characters to roam around in the game world, following a roughly guided or thoroughly defined path. For example in a racing game, the AI opponents need to navigate on the road. And the decision-making algorithms such as our flocking boid algorithm discussed already, can only do well in making decisions. But in the end, it all comes down to dealing with actual movements and steering behaviors. Steering behaviors for AI characters have been in research topics for a couple of decades now. One notable paper in this field is Steering Behaviors for Autonomous Characters, again by Craig Reynolds, presented in 1999 at the Game Developers Conference (GDC). He categorized steering behaviors into the following three layers: Hierarchy of motion behaviors Let me quote the original example from his paper to understand these three layers: "Consider, for example, some cowboys tending a herd of cattle out on the range. A cow wanders away from the herd. The trail boss tells a cowboy to fetch the stray. The cowboy says "giddy-up" to his horse, and guides it to the cow, possibly avoiding obstacles along the way. In this example, the trail boss represents action selection, noticing that the state of the world has changed (a cow left the herd), and setting a goal (retrieve the stray). The steering level is represented by the cowboy who decomposes the goal into a series of simple sub goals (approach the cow, avoid obstacles, and retrieve the cow). A sub goal corresponds to a steering behavior for the cowboy-and-horse team. Using various control signals (vocal commands, spurs, and reins), the cowboy steers his horse towards the target. In general terms, these signals express concepts like go faster, go slower, turn right, turn left, and so on. The horse implements the locomotion level. Taking the cowboy's control signals as input, the horse moves in the indicated direction. This motion is the result of a complex interaction of the horse's visual perception, its sense of balance, and its muscles applying torques to the joints of its skeleton." Then he presented how to design and implement some common and simple steering behaviors for individual AI characters and pairs. Such behaviors include seek and flee, pursue and evade, wander, arrival, obstacle avoidance, wall following, and path following. A* pathfinding There are many games where you can find monsters or enemies that follow the player, or go to a particular point while avoiding obstacles. For example, let's take a look at a typical RTS game. You can select a group of units and click a location where you want them to move or click on the enemy units to attack them. Your units then need to find a way to reach the goal without colliding with the obstacles. The enemy units also need to be able to do the same. Obstacles could be different for different units. For example, an air force unit might be able to pass over a mountain, while the ground or artillery units need to find a way around it. A* (pronounced "A star") is a pathfinding algorithm widely used in games, because of its performance and accuracy. Let's take a look at an example to see how it works. Let's say we want our unit to move from point A to point B, but there's a wall in the way, and it can't go straight towards the target. So, it needs to find a way to point B while avoiding the wall. Top-down view of our map We are looking at a simple 2D example. But the same idea can be applied to 3D environments. In order to find the path from point A to point B, we need to know more about the map such as the position of obstacles. For that we can split our whole map into small tiles, representing the whole map in a grid format, as shown in the following figure: Map represented in a 2D grid The tiles can also be of other shapes such as hexagons and triangles. But we'll just use square tiles here, as that's quite simple and enough for our scenario. Representing the whole map in a grid, makes the search area more simplified, and this is an important step in pathfinding. We can now reference our map in a small 2D array. Our map is now represented by a 5 x 5 grid of square tiles with a total of 25 tiles. We can start searching for the best path to reach the target. How do we do this? By calculating the movement score of each tile adjacent to the starting tile, which is a tile on the map not occupied by an obstacle, and then choosing the tile with the lowest cost. There are four possible adjacent tiles to the player, if we don't consider the diagonal movements. Now, we need to know two numbers to calculate the movement score for each of those tiles. Let's call them G and H, where G is the cost of movement from starting tile to current tile, and H is the cost to reach the target tile from current tile. By adding G and H, we can get the final score of that tile; let's call it F. So we'll be using this formula: F = G + H. Valid adjacent tiles In this example, we'll be using a simple method called Manhattan length (also known as Taxicab geometry), in which we just count the total number of tiles between the starting tile and the target tile to know the distance between them. Calculating G The preceding figure shows the calculations of G with two different paths. We just add one (which is the cost to move one tile) to the previous tile's G score to get the current G score of the current tile. We can give different costs to different tiles. For example, we might want to give a higher movement cost for diagonal movements (if we are considering them), or to specific tiles occupied by, let's say a pond or a muddy road. Now we know how to get G. Let's look at the calculation of H. The following figure shows different H values from different starting tiles to the target tile. You can try counting the squares between them to understand how we get those values. Calculating H So, now we know how to get G and H. Let's go back to our original example to figure out the shortest path from A to B. We first choose the starting tile, and then determine the valid adjacent tiles, as shown in the following figure. Then we calculate the G and H scores of each tile, shown in the lower-left and right corners of the tile respectively. And then the final score F, which is G + H is shown at the top-left corner. Obviously, the tile to the immediate right of the start tile has got the lowest F score. So, we choose this tile as our next movement, and store the previous tile as its parent. This parent stuff will be useful later, when we trace back our final path. Starting position From the current tile, we do the similar process again, determining valid adjacent tiles. This time there are only two valid adjacent tiles at the top and bottom. The left tile is a starting tile, which we've already examined, and the obstacle occupies the right tile. We calculate the G, the H, and then the F score of those new adjacent tiles. This time we have four tiles on our map with all having the same score, six. So, which one do we choose? We can choose any of them. It doesn't really matter in this example, because we'll eventually find the shortest path with whichever tile we choose, if they have the same score. Usually, we just choose the tile added most recently to our adjacent list. This is because later we'll be using some sort of data structure, such as a list to store those tiles that are being considered for the next move. So, accessing the tile most recently added to that list could be faster than searching through the list to reach a particular tile that was added previously. In this demo, we'll just randomly choose the tile for our next test, just to prove that it can actually find the shortest path. Second step So, we choose this tile, which is highlighted with a red border. Again we examine the adjacent tiles. In this step, there's only one new adjacent tile with a calculated F score of 8. So, the lowest score right now is still 6. We can choose any tile with the score 6. Third step So, we choose a tile randomly from all the tiles with the score 6. If we repeat this process until we reach our target tile, we'll end up with a board complete with all the scores for each valid tile. Reach target Now all we have to do is to trace back starting from the target tile using its parent tile. This will give a path that looks something like the following figure: Path traced back So this is the concept of A* pathfinding in a nutshell, without displaying any code. A* is an important concept in the AI pathfinding area, but since Unity 3.5, there are a couple of new features such as automatic navigation mesh generation and the Nav Mesh Agent, which we'll see roughly in the next section and then in more detail later. These features make implementing pathfinding in your games very much easier. In fact, you may not even need to know about A* to implement pathfinding for your AI characters. Nonetheless, knowing how the system is actually working behind the scenes will help you to become a solid AI programmer. Unfortunately, those advanced navigation features in Unity are only available in the Pro version at this moment. A navigation mesh Now we have some idea of A* pathfinding techniques. One thing that you might notice is that using a simple grid in A* requires quite a number of computations to get a path which is the shortest to the target, and at the same time avoids the obstacles. So, to make it cheaper and easier for AI characters to find a path, people came up with the idea of using waypoints as a guide to move AI characters from the start point to the target point. Let's say we want to move our AI character from point A to point B, and we've set up three waypoints as shown in the following figure: Waypoints All we have to do now is to pick up the nearest waypoint, and then follow its connected node leading to the target waypoint. Most of the games use waypoints for pathfinding, because they are simple and quite effective in using less computation resources. However, they do have some issues. What if we want to update the obstacles in our map? We'll also have to place waypoints for the updated map again, as shown in the following figure: New waypoints Following each node to the target can mean the AI character moves in zigzag directions. Look at the preceding figures; it's quite likely that the AI character will collide with the wall where the path is close to the wall. If that happens, our AI will keep trying to go through the wall to reach the next target, but it won't be able to and it will get stuck there. Even though we can smooth out the zigzag path by transforming it to a spline and do some adjustments to avoid such obstacles, the problem is the waypoints don't give any information about the environment, other than the spline connected between two nodes. What if our smoothed and adjusted path passes the edge of a cliff or a bridge? The new path might not be a safe path anymore. So, for our AI entities to be able to effectively traverse the whole level, we're going to need a tremendous number of waypoints, which will be really hard to implement and manage. Let's look at a better solution, navigation mesh. A navigation mesh is another graph structure that can be used to represent our world, similar to the way we did with our square tile-based grid or waypoints graph. Navigation mesh A navigation mesh uses convex polygons to represent the areas in the map that an AI entity can travel. The most important benefit of using a navigation mesh is that it gives a lot more information about the environment than a waypoint system. Now we can adjust our path safely, because we know the safe region in which our AI entities can travel. Another advantage of using a navigation mesh is that we can use the same mesh for different types of AI entities. Different AI entities can have different properties such as size, speed, and movement abilities. A set of waypoints is tailored for human, AI may not work nicely for flying creatures or AI controlled vehicles. Those might need different sets of waypoints. Using a navigation mesh can save a lot of time in such cases. But generating a navigation mesh programmatically based on a scene, is a somewhat complicated process. Fortunately, Unity 3.5 introduced a built-in navigation mesh generator (Pro only feature). Instead, we'll learn how to use Unity's navigation mesh for generating features to easily implement our AI pathfinding. The behavior trees Behavior trees are the other techniques used to represent and control the logic behind AI characters. They have become popular for the applications in AAA games such as Halo and Spore. Previously, we have briefly covered FSM. FSMs provide a very simple way to define the logic of an AI character, based on the different states and transitions between them. However, FSMs are considered difficult to scale and re-use existing logic. We need to add many states and hard-wire many transitions, in order to support all the scenarios, which we want our AI character to consider. So, we need a more scalable approach when dealing with large problems. behavior trees are a better way to implement AI game characters that could potentially become more and more complex. The basic elements of behavior trees are tasks, where states are the main elements for FSMs. There are a few different tasks such as Sequence, Selector, and Parallel Decorator. This is quite confusing. The best way to understand this is to look at an example. Let's try to translate our example from the FSM section using a behavior tree. We can break all the transitions and states into tasks. Tasks Let's look at a Selector task for this Behavior tree. Selector tasks are represented with a circle and a question mark inside. First it'll choose to attack the player. If the Attack task returns success, the Selector task is done and will go back to the parent node, if there is one. If the Attack task fails, it'll try the Chase task. If the Chase task fails, it'll try the Patrol task. Selector task What about the tests? They are also one of the tasks in the behavior trees. The following diagram shows the use of Sequence tasks, denoted by a rectangle with an arrow inside it. The root selector may choose the first Sequence action. This Sequence action's first task is to check whether the player character is close enough to attack. If this task succeeds, it'll proceed with the next task, which is to attack the player. If the Attack task also returns success, the whole sequence will return success, and the selector is done with this behavior, and will not continue with other Sequence tasks. If the Close enough to attack? task fails, then the Sequence action will not proceed to the Attack task, and will return a failed status to the parent selector task. Then the selector will choose the next task in the sequence, Lost or Killed Player?. Sequence tasks The other two common components are Parallel and Decorator. A Parallel task will execute all of its child tasks at the same time, while the Sequence and Selector tasks only execute their child tasks one by one. Decorator is another type of task that has only one child. It can change the behavior of its own child's tasks, which includes whether to run its child's task or not, how many times it should run, and so on. We'll study how to implement a basic behavior tree system later. There's a free add-on for Unity called Behave in the Unity Asset Store. Behave is a useful, free GUI editor to set up behavior trees of AI characters, and we'll look at it in more detail later as well. Locomotion Animals (including humans) have a very complex musculoskeletal system (the locomotor system) that gives them the ability to move around the body using the muscular and skeletal systems. We know where to put our steps when climbing a ladder, stairs, or on uneven terrain, and we know how to balance our body to stabilize all the fancy poses we want to make. We can do all this using our bones, muscles, joints, and other tissues, collectively described as our locomotor system. Now put that into our game development perspective. Let's say we've a human character who needs to walk on both even and uneven surfaces, or on small slopes, and we have only one animation for a "walk" cycle. With the lack of a locomotor system in our virtual character, this is how it would look: Climbing stair without locomotion First we play the walk animation and advance the player forward. Now the character knows it's penetrating the surface. So, the collision detection system will pull the character up above the surface to prevent this penetration. This is how we usually set up the movement on an uneven surface. Even though it doesn't give a realistic look and feel, it does the job and is cheap to implement. Let's take a look at how we really walk up stairs. We put our step firmly on the staircase, and using this force we pull up the rest of our body for the next step. This is how we do it in real life with our advanced locomotor system. However, it's not so simple to implement this level of realism inside games. We'll need a lot of animations for different scenarios, which include climbing ladders, walking/running up stairs, and so on. So, only the large studios with a lot of animators could pull this off in the past, until we came up with an automated system. With a locomotion system Fortunately, Unity 3D has an extension that can do just that, which is a locomotion system. Locomotion system Unity extension This system can automatically blend our animated walk/run cycles, and adjust the movements of the bones in the legs to ensure that the feet step correctly on the ground. It can also adjust the original animations made for a specific speed and direction on any surface, arbitrary steps, and slopes. We'll see how to use this locomotion system to apply realistic movement to our AI characters. Dijkstra's algorithm The Dijkstra's algorithm, named after professor Edsger Dijkstra, who devised the algorithm, is one of the most famous algorithms for finding the shortest paths in a graph with non-negative edge path costs. The algorithm was originally designed to solve the shortest path problem in the context of mathematical graph theory. And it's designed to find all the shortest paths from a starting node to all the other nodes in the graph. Since most of the games only need the shortest path between one starting point and one target point, all the other paths generated or found by this algorithm are not really useful. We can stop the algorithm, once we find the shortest path from a single starting point to a target point. But still it'll try to find all the shortest paths from all the points it has visited. So, this algorithm is not efficient enough to be used in most games. And we won't be doing a Unity demo of Dijkstra's algorithm in this article as well. However, Dijkstra's algorithm is an important algorithm for the games that require strategic AI that needs as much information as possible about the map to make tactical decisions. It has many applications other than games, such as finding the shortest path in network routing protocols. Summary Game AI and academic AI have different objectives. Academic AI researches try to solve real-world problems, and prove a theory without much limited resources. Game AI focuses on building NPCs within limited resources that seems to be intelligent to the player. Objective of AI in games is to provide a challenging opponent that makes the game more fun to play with. We also learned briefly about the different AI techniques that are widely used in games such as finite state machines (FSMs), random and probability, sensor and input system, flocking and group behaviors, path following and steering behaviors, AI path finding, navigation mesh generation, and behavior trees. Resources for Article: Further resources on this subject: Unity 3-0 Enter the Third Dimension [Article] Introduction to Game Development Using Unity 3D [Article] Unity Game Development: Welcome to the 3D world [Article]
Read more
  • 0
  • 0
  • 41338

article-image-using-opencl
Packt
28 Aug 2013
15 min read
Save for later

Using OpenCL

Packt
28 Aug 2013
15 min read
(For more resources related to this topic, see here.) Let's start the journey by looking back into the history of computing and why OpenCL is important from the respect that it aims to unify the software programming model for heterogeneous devices. The goal of OpenCL is to develop a royalty-free standard for cross-platform, parallel programming of modern processors found in personal computers, servers, and handheld/embedded devices. This effort is taken by "The Khronos Group" along with the participation of companies such as Intel, ARM, AMD, NVIDIA, QUALCOMM, Apple, and many others. OpenCL allows the software to be written once and then executed on the devices that support it. In this way it is akin to Java, this has benefits because software development on these devices now has a uniform approach, and OpenCL does this by exposing the hardware via various data structures, and these structures interact with the hardware via Application Programmable Interfaces ( APIs ). Today, OpenCL supports CPUs that includes x86s, ARM and PowerPC and GPUs by AMD, Intel, and NVIDIA. Developers can definitely appreciate the fact that we need to develop software that is cross-platform compatible, since it allows the developers to develop an application on whatever platform they are comfortable with, without mentioning that it provides a coherent model in which we can express our thoughts into a program that can be executed on any device that supports this standard. However, what cross-platform compatibility also means is the fact that heterogeneous environments exists, and for quite some time, developers have to learn and grapple with the issues that arise when writing software for those devices ranging from execution model to memory systems. Another task that commonly arose from developing software on those heterogeneous devices is that developers were expected to express and extract parallelism from them as well. Before OpenCL, we know that various programming languages and their philosophies were invented to handle the aspect of expressing parallelism (for example, Fortran, OpenMP, MPI, VHDL, Verilog, Cilk, Intel TBB, Unified parallel C, Java among others) on the device they executed on. But these tools were designed for the homogeneous environments, even though a developer may think that it's to his/her advantage, since it adds considerable expertise to their resume. Taking a step back and looking at it again reveals that is there is no unified approach to express parallelism in heterogeneous environments. We need not mention the amount of time developers need to be productive in these technologies, since parallel decomposition is normally an involved process as it's largely hardware dependent. To add salt to the wound, many developers only have to deal with homogeneous computing environments, but in the past few years the demand for heterogeneous computing environments grew. The demand for heterogeneous devices grew partially due to the need for high performance and highly reactive systems, and with the "power wall" at play, one possible way to improve more performance was to add specialized processing units in the hope of extracting every ounce of parallelism from them, since that's the only way to reach power efficiency. The primary motivation for this shift to hybrid computing could be traced to the research headed entitled Optimizing power using Transformations by Anantha P. Chandrakasan. It brought out a conclusion that basically says that many-core chips (which run at a slightly lower frequency than a contemporary CPU) are actually more power-efficient. The problem with heterogeneous computing without a unified development methodology, for example, OpenCL, is that developers need to grasp several types of ISA and with that the various levels of parallelism and their memory systems are possible. CUDA, the GPGPU computing toolkit, developed by NVIDIA deserves a mention not only because of the remarkable similarity it has with OpenCL, but also because the toolkit has a wide adoption in academia as well as industry. Unfortunately CUDA can only drive NVIDIA's GPUs. The ability to extract parallelism from an environment that's heterogeneous is an important one simply because the computation should be parallel, otherwise it would defeat the entire purpose of OpenCL. Fortunately, major processor companies are part of the consortium led by The Khronos Group and actively realizing the standard through those organizations. Unfortunately the story doesn't end there, but the good thing is that we, developers, realized that a need to understand parallelism and how it works in both homogeneous and heterogeneous environments. OpenCL was designed with the intention to express parallelism in a heterogeneous environment. For a long time, developers have largely ignored the fact that their software needs to take advantage of the multi-core machines available to them and continued to develop their software in a single-threaded environment, but that is changing (as discussed previously). In the many-core world, developers need to grapple with the concept of concurrency, and the advantage of concurrency is that when used effectively, it maximizes the utilization of resources by providing progress to others while some are stalled. When software is executed concurrently with multiple processing elements so that threads can run simultaneously, we have parallel computation. The challenge that the developer has is to discover that concurrency and realize it. And in OpenCL, we focus on two parallel programming models: task parallelism and data parallelism. Task parallelism means that developers can create and manipulate concurrent tasks. When developers are developing a solution for OpenCL, they would need to decompose a problem into different tasks and some of those tasks can be run concurrently, and it is these tasks that get mapped to processing elements ( PEs ) of a parallel environment for execution. On the other side of the story, there are tasks that cannot be run concurrently and even possibly interdependent. An additional complexity is also the fact that data can be shared between tasks. When attempting to realize data parallelism, the developer needs to readjust the way they think about data and how they can be read and updated concurrently. A common problem found in parallel computation would be to compute the sum of all the elements given in an arbitrary array of values, while storing the intermediary summed value and one possible way to do this is illustrated in the following diagram and the operator being applied there, that is, is any binary associative operator. Conceptually, the developer could use a task to perform the addition of two elements of that input to derive the summed value. Whether the developer chooses to embody task/data parallelism is dependent on the problem, and an example where task parallelism would make sense will be by traversing a graph. And regardless of which model the developer is more inclined with, they come with their own sets of problems when you start to map the program to the hardware via OpenCL. And before the advent of OpenCL, the developer needs to develop a module that will execute on the desired device and communication, and I/O with the driver program. An example example of this would be a graphics rendering program where the CPU initializes the data and sets everything up, before offloading the rendering to the GPU. OpenCL was designed to take advantage of all devices detected so that resource utilization is maximized, and hence in this respect it differs from the "traditional" way of software development. Now that we have established a good understanding of OpenCL, we should spend some time understanding how a developer can learn it. And not to fret, because every project you embark with, OpenCL will need you to understand the following: Discover the makeup of the heterogeneous system you are developing for Understand the properties of those devices by probing it Start the parallel program decomposition using either or all of task parallelism or data parallelism, by expressing them into instructions also known as kernels that will run on the platform Set up data structures for the computation Manipulate memory objects for the computation Execute the kernels in the order that's desired on the proper device Collate the results and verify for correctness Next, we need to solidify the preceding points by taking a deeper look into the various components of OpenCL. The following components collectively make up the OpenCL architecture: Platform Model: A platform is actually a host that is connected to one or more OpenCL devices. Each device comprises possibly multiple compute units ( CUs ) which can be decomposed into one or possibly multiple processing elements, and it is on the processing elements where computation will run. Execution Model: Execution of an OpenCL program is such that the host program would execute on the host, and it is the host program which sends kernels to execute on one or more OpenCL devices on that platform. When a kernel is submitted for execution, an index space is defined such that a work item is instantiated to execute each point in that space. A work item would be identified by its global ID and it executes the same code as expressed in the kernel. Work items are grouped into work groups and each work group is given an ID commonly known as its work group ID, and it is the work group's work items that get executed concurrently on the PEs of a single CU. That index space we mentioned earlier is known as NDRange describing an N-dimensional space, where N can range from one to three. Each work item has a global ID and a local ID when grouped into work groups, that is distinct from the other and is derived from NDRange. The same can be said about work group IDs. Let's use a simple example to illustrate how they work. Given two arrays, A and B, of 1024 elements each, we would like to perform the computation of vector multiplication also known as dot product, where each element of A would be multiplied by the corresponding element in B. The kernel code would look something as follows: __kernel void vector_multiplication(__global int* a, __global int* b, __global int* c) {int threadId = get_global_id(0); // OpenCL functionc[i] = a[i] * b[i];} In this scenario, let's assume we have 1024 processing elements and we would assign one work item to perform exactly one multiplication, and in this case our work group ID would be zero (since there's only one group) and work items IDs would range from {0 … 1023}. Recall what we discussed earlier, that it is the work group's work items that can executed on the PEs. Hence reflecting back, this would not be a good way of utilizing the device. In this same scenario, let's ditch the former assumption and go with this: we still have 1024 elements but we group four work items into a group, hence we would have 256 work groups with each work group having an ID ranging from {0 … 255}, but it is noticed that the work item's global ID still would range from {0 … 1023} simply because we have not increased the number of elements to be processed. This manner of grouping work items into their work groups is to achieve scalability in these devices, since it increases execution efficiency by ensuring all PEs have something to work on. The NDRange can be conceptually mapped into an N-dimensional grid and the following diagram illustrates how a 2DRange works, where WG-X denotes the length in rows for a particular work group and WG-Y denotes the length in columns for a work group, and how work items are grouped including their respective IDs in a work group. Before the execution of the kernels on the device(s), the host program plays an important role and that is to establish context with the underlying devices and laying down the order of execution of the tasks. The host program does the context creation by establishing the existence (creating if necessary) of the following: All devices to be used by the host program The OpenCL kernels, that is, functions and their abstractions that will run on those devices The memory objects that encapsulated the data to be used / shared by the OpenCL kernels. Once that is achieved, the host needs to create a data structure called a command queue that will be used by the host to coordinate the execution of the kernels on the devices and commands are issued to this queue and scheduled onto the devices. A command queue can accept: kernel execution commands, memory transfer commands, and synchronization commands. Additionally, the command queues can execute the commands in-order, that is, in the order they've been given, or out-of-order. If the problem is decomposed into independent tasks, it is possible to create multiple command queues targeting different devices and scheduling those tasks onto them, and then OpenCL will run them concurrently. Memory Model: So far, we have understood the execution model and it's time to introduce the memory model that OpenCL has stipulated. Recall that when the kernel executes, it is actually the work item that is executing its instance of the kernel code. Hence the work item needs to read and write the data from memory and each work item has access to four types of memories: global, constant, local, and private. These memories vary from size as well as accessibilities, where global memory has the largest size and is most accessible to work items, whereas private memory is possibly the most restrictive in the sense that it's private to the work item. The constant memory is a read-only memory where immutable objects are stored and can be shared with all work items. The local memory is only available to all work items executing in the work group and is held by each compute unit, that is, CU-specific. The application running on the host uses the OpenCL API to create memory objects in global memory and will enqueue memory commands to the command queue to operate on them. The host's responsibility is to ensure that data is available to the device when the kernel starts execution, and it does so by copying data or by mapping/unmapping regions of memory objects. During a typical data transfer from the host memory to the device memory, OpenCL commands are issued to queues which may be blocking or non-blocking. The primary difference between a blocking and non-blocking memory transfer is that in the former, the function calls return only once (after being queued) it is deemed safe, and in the latter the call returns as soon as the command is enqueued. Memory mapping in OpenCL allows a region of memory space to be available for computation and this region can be blocking or non-blocking and the developer can treat this space as readable or writeable or both. Hence forth, we are going to focus on getting the basics of OpenCL by letting our hands get dirty in developing small OpenCL programs to understand a bit more, programmatically, how to use the platform and execution model of OpenCL. The OpenCL specification Version 1.2 is an open, royalty-free standard for general purpose programming across various devices ranging from mobile to conventional CPUs, and lately GPUs through an API and the standard at the time of writing supports: Data and task based parallel programming models Implements a subset of ISO C99 with extensions for parallelism with some restrictions such as recursion, variadic functions, and macros which are not supported Mathematical operations comply to the IEEE 754 specification Porting to handheld and embedded devices can be accomplished by establishing configuration profiles Interoperability with OpenGL, OpenGL ES, and other graphics APIs Throughout this article, we are going to show you how you can become proficient in programming OpenCL. As you go through the article, you'll discover not only how to use the API to perform all kinds of operations on your OpenCL devices, but you'll also learn how to model a problem and transform it from a serial program to a parallel program. More often than not, the techniques you'll learn can be transferred to other programming toolsets. In the toolsets, I have worked with OpenCLTM, CUDATM, OpenMPTM, MPITM, Intel thread building blocksTM, CilkTM, CilkPlusTM, which allows the developer to express parallelism in a homogeneous environment and find the entire process of learning the tools to application of knowledge to be classified into four parts. These four phases are rather common and I find it extremely helpful to remember them as I go along. I hope you will be benefited from them as well. Finding concurrency: The programmer works in the problem domain to identify the available concurrency and expose it to use in the algorithm design Algorithm structure: The programmer works with high-level structures for organizing a parallel algorithm Supporting Structures: This refers to how the parallel program will be organized and the techniques used to manage shared data Implementation mechanisms: The final step is to look at specific software constructs for implementing a parallel program. Don't worry about these concepts, they'll be explained as we move through the article. The next few recipes we are going to examine have to do with understanding the usage of OpenCL APIs, by focusing our efforts in understanding the platform model of the architecture.
Read more
  • 0
  • 0
  • 1368

article-image-salesforce-crm-functions
Packt
27 Aug 2013
3 min read
Save for later

Salesforce CRM Functions

Packt
27 Aug 2013
3 min read
(For more resources related to this topic, see here.) Functional overview of Salesforce CRM The Salesforce CRM functions are related to each other and, as mentioned previously, have cross-over areas which can be represented as shown in the following diagram: Marketing administration Marketing administration is available in Salesforce CRM under the application suite known as the Marketing Cloud. The core functionality enables organizations to manage marketing campaigns from initiation to lead development in conjunction with the sales team. The features in the marketing application can help measure the effectiveness of each campaign by analyzing the leads and opportunities generated as a result of specific marketing activities. Salesforce automation Salesforce automation is the core feature set within Salesforce CRM and is used to manage the sales process and activities. It enables salespeople to automate manual and repetitive tasks and provides them with information related to existing and prospective customers. In Salesforce CRM, Salesforce automation is known as the Sales Cloud, and helps the sales people manage sales activities, leads and contact records, opportunities, quotes, and forecasts. Customer service and support automation Customer service and support automation within Salesforce CRM is known as the Service Cloud, and allows support teams to automate and manage the requests for service and support by existing customers. Using the Service Cloud features, organizations can handle customer requests, such as the return of faulty goods or repairs, complaints, or provide advice about products and services. Associated with the functional areas, described previously, are features and mechanisms to help users and customers collaborate and share information known as enterprise social networking. Enterprise social networking Enterprise social network capabilities within Salesforce CRM enable organizations to connect with people and securely share business information in real time. Social networking within an enterprise serves to connect both employees and customers and enables business collaboration. In Salesforce CRM, the enterprise social network suite is known as Salesforce Chatter. Salesforce CRM record life cycle The capabilities of Salesforce CRM provides for the processing of campaigns through to customer acquisition and beyond as shown in the following diagram: At the start of the process, it is the responsibility of the marketing team to develop suitable campaigns in order to generate leads. Campaign management is carried out using the Marketing Administration tools and has links to the lead and also any opportunities that have been influenced by the campaign. When validated, leads are converted to accounts, contacts, and opportunities. This can be the responsibility of either the marketing or sales teams and requires a suitable sales process to have been agreed upon. In Salesforce CRM, an account is the company or organization and a contact is an individual associated with an account. Opportunities can either be generated from lead conversion or may be entered directly by the sales team. As described earlier in this article, the structure of Salesforce requires account ownership to be established which sees inherited ownership of the opportunity. Account ownership is usually the responsibility of the sales team. Opportunities are worked through a sales process using sales stages where the stage is advanced to the point where they are set as won/closed and become sales. Opportunity information should be logged in the organization's financial system. Upon financial completion and acceptance of the deal (and perhaps delivery of the goods or service), the post-customer acquisition process is then enabled where the account and contact can be recognized as a customer. Here the customer relationships concerning incidents and requests are managed by escalating cases within the customer services and support automation suite.
Read more
  • 0
  • 0
  • 8101

article-image-irc-style-chat-tcp-server-and-event-bus
Packt
27 Aug 2013
6 min read
Save for later

IRC-style chat with TCP server and event bus

Packt
27 Aug 2013
6 min read
(For more resources related to this topic, see here.) Step 1 – fresh start In a new folder called, for example, 1_PubSub_Chat, let's open our editor of choice and create here a file called pubsub_chat.js. Also, make sure that you have a terminal window open and you moved into the newly created project directory. Step 2 – creating the TCP server TCP servers are called net servers in Vert.x. Creating and using a net server is really similar to HTTP servers: Obtain the vertx bridge object to access the framework features: var vertx = require('vertx'); /* 1 */var netServer = vertx.createNetServer(); /* 2 */netServer.listen(1234); /* 3 */ Ask Vert.x to create a TCP server (called NetServer in Vert.x). Actually, start the server by telling it to listen on TCP port 1234. Let's test whether this works. This time we need another terminal to run the telnet command: $ telnet localhost 1234 The terminal should now be connected and waiting to send/receive characters. If you have "connection refused" errors, make sure the server is running. Step 3 – adding a connect handler Now, we need to place a block of code to be executed as soon as a client connects: Define a handler function. This function will be called every time a client connects to the server: var vertx = require('vertx')var server = vertx.createNetServer().connectHandler(function(socket) {// Composing a client address stringaddr = socket.remoteAddress();addr = addr.ipaddress + addr.port;socket.write('Welcome to the chat ' + addr + '!');}).listen(1234) A NetServer connect handler accepts the socket object as a parameter; this object is our gateway to reading, writing, or closing the connection to a client. Use the socket object to write a greeting to the newly connected clients. If we test this one as in step 2 (Step 2 – creating the TCP server), we see that the server now welcomes us with a message containing an identifier of the client as its origin host and origin port. Step 4 – adding a data handler We just learned how to execute a block of code at the moment in which the client connects. However now we are interested in doing something else at the time when we receive new data from a client connection. The socket object we used in the previous step for writing data back to the client, accepts a handler function too: the data handler. Let's add one: Add a data handler function to the socket object. This is going to be called every time the client sends a new string of data: var vertx = require('vertx') var server = vertx.createNetServer().connectHandler( function(socket) { // Composing a client address string addr = socket.remoteAddress(); addr = addr.ipaddress + addr.port; socket.write('Welcome to the chat ' + addr + '!'); socket.dataHandler(function(data) { var now = new Date(); now = now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds(); var msg = now + ' <' + addr + '> ' + data; socket.write(msg); }) }).listen(1234) React to the new data event by writing the same data back to the socket (plus a prefix). What we have now is a sort of an echo server, which returns back to the sender the same message with a prefix string. Step 5 – adding the event bus magic The base requirement of a chat server is that every time a client sends a message, the rest of the connected clients should receive it. We will use event bus, the messaging service provided by the framework, to send (publish) received messages to a broadcast address. Each client will subscribe to the address upon connection and receive other clients' messages from there: Add a data handler function to the socket object: var vertx = require('vertx') var server = vertx.createNetServer().connectHandler( function(socket) { // Composing a client address string addr = socket.remoteAddress(); addr = addr.ipaddress + addr.port; socket.write('Welcome to the chat ' + addr + '!'); vertx.eventBus.registerHandler('broadcast_address', function(event){ socket.write(event); }); socket.dataHandler(function(data) { var now = new Date(); now = now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds(); var msg = now + ' <' + addr + '> ' + data; vertx.eventBus.publish('broadcast_address', msg); }) }).listen(1234) As soon as a client connects, they listen to the event bus for new data to be published on the address broadcast_address. When a client sends a string of characters to the server, this data is published to the broadcast address, triggering a handler function that writes the string to all the clients' sockets. The chat server is now complete! To try it out, just open three terminals: Terminal 1: $ vertx run pubsub_chat.js Terminal 2: $ telnet localhost 1234 Terminal 3: $ telnet localhost 1234 Now, we have a server and two clients running and connected. Type something in terminal 2 or 3 and see the message being broadcast to both the other windows: $ telnet localhost 1234Trying ::1...Connected to localhost.Escape character is '^]'.Hello from terminal two!13:6:56 <0:0:0:0:0:0:0:155991> Hello from terminal two!13:7:24 <0:0:0:0:0:0:0:155992> Hi there, here's terminal three!13:7:56 <0:0:0:0:0:0:0:155992> Great weather today! Step 6 – Organizing a more complex project Since Vert.x is a polyglot platform, we can choose to write an application (or a part of it) in either of the many supported languages. The granularity of the language choice is at verticle level. It's important to give a good architecture to a non-trivial project from the beginning. Follow this list of generic principles to avoid performance bottlenecks or the need for massive refactoring in the future: Wrap synchronous libraries or legacy code inside a worker verticle (or a module). This will keep the blocking code away from the event loop threads. Divide the problem in isolated domains and write a verticle to handle each of them (for example, database persistor verticle, web server verticle, authenticator verticle, and cache manager verticle). Use a startup verticle. This will be the single entry point to the application. Its responsibilities will be to: Validate the configuration file Programmatically deploy other verticles in the correct order Decide how many instances of a verticle to create (the decision might depend on the environment: for example, the amount of available processors) Register periodic tasks Summary: In this article, we learned in a step-wise procedure how we can create an Internet Relay Chat using the TCP server, and interconnect the server with the clients using an event bus, and enable different types of communication between them. Resources for Article: Further resources on this subject: Getting Started with Zombie.js [Article] Building a Chat Application [Article] Accessing and using the RDF data in Stanbol [Article]
Read more
  • 0
  • 0
  • 3427
article-image-schemas-and-models
Packt
27 Aug 2013
12 min read
Save for later

Schemas and Models

Packt
27 Aug 2013
12 min read
(For more resources related to this topic, see here.) So what is a schema? At its simplest, a schema is a way to describe the structure of data. Typically this involves giving each piece of data a label, and stating what type of data it is, for example, a number, date, string, and so on. In the following example, we are creating a new Mongoose schema called userSchema. We are stating that a database document using this schema will have three pieces of data, which are as follows: name: This data will contain a string email: This will also contain a string value createdOn: This data will contain a date The following is the schema definition: var userSchema = new mongoose.Schema({name: String,email: String,createdOn: Date}); Field sizes Note that, unlike some other systems there is no need to set the field size. This can be useful if you need to change the amount of data stored in a particular object. For example, your system might impose a 16-character limit on usernames, so you set the size of the field to 16 characters. Later, you realize that you want to encrypt the usernames, but this will double the length of the data stored. If your database schema uses fixed field sizes, you will need to refactor it, which can take a long time on a large database. With Mongoose, you can just start encrypting that data object without worrying about it. If you're storing large documents, you should bear in mind that MongoDB imposes a maximum document size of 16 MB. There are ways around even this limit, using the MongoDB GridFS API. Data types allowed in schemas There are eight types of data that can—by default—be set in a Mongoose schema. These are also referred to as SchemaTypes; they are: String Number Date Boolean Buffer ObjectId Mixed Array The first four SchemaTypes are self-explanatory, but let's take a quick look at them all. String This SchemaType stores a string value, UTF-8 encoded. Number This SchemaType stores a number value, with restrictions. Mongoose does not natively support long and double datatypes for example, although MongoDB does. However, Mongoose can be extended using plugins to support these other types. Date This SchemaType holds a date and time object, typically returned from MongoDB as an ISODate object, for example, ISODate("2013-04-03T12:56:26.009Z"). Boolean This SchemaType has only two values: true or false. Buffer This SchemaType is primarily used for storing binary information, for example, images stored in MongoDB. ObjectId This SchemaType is used to assign a unique identifier to a key other than _id. Rather than just specifying the type of ObjectId you need to specify the fully qualified version Schema.Types.ObjectId. For example: projectSchema.add({owner: mongoose.Schema.Types.ObjectId}); Mixed A mixed data object can contain any type of data. It can be declared either by setting an empty object, or by using the fully qualified Schema.Types.Mixed. These following two commands will do the same thing: vardjSchema= new mongoose.Schema({mixedUp: {}});vardjSchema= new mongoose.Schema({mixedUp: Schema.Types.Mixed}); While this sounds like it might be great, there is a big caveat. Changes to data of mixed type cannot be automatically detected by Mongoose, so it doesn't know that it needs to save them. Tracking changes to Mixed type As Mongoose can't automatically see changes made to mixed type of data, you have to manually declare when the data has changed. Fortunately, Mongoose exposes a method called markModified to do just this, passing it the path of the data object that has changed. dj.mixedUp = { valueone: "a new value" };dj.markModified('mixedUp');dj.save(); Array The array datatype can be used in two ways. First, a simple array of values of the same data type, as shown in the following code snippet: var userSchema = new mongoose.Schema({name: String,emailAddresses: [String]}); Second, the array datatype can be used to store a collection of subdocuments using nested schemas. Here's an example in the following of how this can work: var emailSchema = new mongoose.Schema({email: String,verified: Boolean});var userSchema = new mongoose.Schema({name: String,emailAddresses: [emailSchema]}); Warning – array defined as mixed type A word of caution. If you declare an empty array it will be treated as mixed type, meaning that Mongoose will not be able to automatically detect any changes made to the data. So avoid these two types of array declaration, unless you intentionally want a mixed type. var emailSchema = new mongoose.Schema({addresses: []});var emailSchema = new mongoose.Schema({addresses: Array}); Custom SchemaTypes If your data requires a different datatype which is not covered earlier in this article, Mongoose offers the option of extending it with custom SchemaTypes. The extension method is managed using Mongoose plugins. Some examples of SchemaType extensions that have already been created are: long, double, RegEx, and even email. Where to write the schemas As your schemas sit on top of Mongoose, the only absolute is that they need to be defined after Mongoose is required. You don't need an active or open connection to define your schemas. That being said it is advisable to make your connection early on, so that it is available as soon as possible, bearing in mind that remote database or replica sets may take longer to connect than your localhost development server. While no action can be taken on the database through the schemas and models until the connection is open, Mongoose can buffer requests made from when the connection is defined. Mongoose models also rely on the connection being defined, so there's another reason to get the connection set up early in the code and then define the schemas and models. Writing a schema Let's write the schema for a User in our MongoosePM application. The first thing we have to do is declare a variable to hold the schema. I recommend taking the object name (for example, user or project) and adding Schema to the end of it. This makes following the code later on super easy. The second thing we need to do is create a new Mongoose schema object to assign to this variable. The skeleton of this is as follows: var userSchema = new mongoose.Schema({ }); We can add in the basic values of name, email, and createdOn that we looked at earlier, giving us our first user schema definition. var userSchema = new mongoose.Schema({name: String,email: String,createdOn: Date}); Modifying an existing schema Suppose we run the application with this for a while, and then decide that we want to record the last time each user logged on, and the last time their record was modified. No problem! We don't have to refactor the database or take it offline while we upgrade the schema, we simply add a couple of entries to the Mongoose schema. If a key requested in the schema doesn't exist, neither Mongoose nor MongoDB will throw errors, Mongoose will just return null values. When saving the MongoDB documents, the new keys and values will be added and stored as required. If the value is null, then the key is not added. So let's add modifiedOn and lastLogin to our userSchema: var userSchema = new mongoose.Schema({name: String,email: String,createdOn: Date,modifiedOn: Date,lastLogin: Date}); Setting a default value Mongoose allows us to set a default value for a data key when the document is first created. Looking at our schema created earlier, a possible candidate for this is createdOn. When a user first signs up, we want the date and time to be set. We could do this by adding a timestamp to the controller function when we create a user, or to make a point we can modify the schema to set a default value. To do this, we need to change the information we are sending about the createdOn data object. What we have currently is: createdOn: Date This is short for: createdOn: { type: Date } We can add another entry to this object to set a default value here, using the JavaScript Date object: createdOn: { type: Date, default: Date.now } Now every time a new user is created its createdOn value will be set to the current date and time. Note that in JavaScript default is a reserved word. While the language allows reserved words to be used as keys, some IDEs and linters regard it as an error. If this causes issues for you or your environment, you can wrap it in quotes, like in the following code snippet: createdOn: { type: Date, 'default': Date.now } Only allowing unique entries If we want to ensure that there is only ever one user per e-mail address, we can specify that the email field should be unique. email: {type: String, unique:true} With this in place, when saving to the database, MongoDB will check to see if the e-mail value already exists in another document. If it finds it, MongoDB (not Mongoose) will return an E11000 error. Note that this approach also defines a MongoDB index on the email field. Our final User schema Your userSchema should now look like the following: var userSchema = new mongoose.Schema({name: String,email: {type: String, unique:true},createdOn: { type: Date, default: Date.now },modifiedOn: Date,lastLogin: Date}); A corresponding document from the database would look like the following (line breaks are added for readability): { "__v" : 0,"_id" : ObjectId("5126b7a1f8a44d1e32000001"),"createdOn" : ISODate("2013-02-22T00:11:13.436Z"),"email" : "simon@theholmesoffice.com","lastLogin" : ISODate("2013-04-03T12:54:42.734Z"),"modifiedOn" : ISODate("2013-04-03T12:56:26.009Z"),"name" : "Simon Holmes" } What's that "__v" thing? You may have noticed a data entity in the document that we didn't set: __v. This is an internal versioning number automatically set by Mongoose when a document is created. It doesn't increment when a document is changed, but instead is automatically incremented whenever an array within the document is updated in such a way that might cause the indexed position of some of the entries to have changed. Why is this needed? When working with an array you will typically access the individual elements through their positional index, for example, myArray[3]. But what happens if somebody else deletes the element in myArray[2] while you are editing the data in myArray[3]? Your original data is now contained in myArray[2] but you don't know this, so you quite happily overwrite whatever data is now stored in myArray[3]. The __v gives you a method to be able to sanity check this, and prevent this scenario from happening. Defining the Project schema As part of our MongoosePM application we also need to think about Projects. After all, PM here does stand for Project Manager. Let's take what we've learned and create the Project schema. We are going to want a few types of data to start with: projectName: A string containing the name of the project. createdOn: The date when the document was first created and saved. This option is set to automatically save the current date and time. modifiedOn: The date and time when the document was last changed. createdBy: A string that will for now contain the unique ID of the user who created the project. tasks: A string to hold task information. Transforming these requirements into a Mongoose schema definition, we create this in the following: varprojectSchema = new mongoose.Schema({projectName: String,createdOn: Date,modifiedOn: { type: Date, default: Date.now },createdBy: String,tasks: String}); This is our starting point, and we will build upon it. For now we have these basic data objects as mentioned previously in this article. Here's an example of a corresponding document from the database (line breaks added for readability): { "projectName" : "Another test","createdBy" : "5126b7a1f8a44d1e32000001","createdOn" : ISODate("2013-04-03T17:47:51.031Z"),"tasks" : "Just a simple task","_id" : ObjectId("515c6b47596acf8e35000001"),"modifiedOn" : ISODate("2013-04-03T17:47:51.032Z"),"__v" : 0 } Improving the Project schema Throughout the rest of the article we will be improving this schema, but the beauty of using Mongoose is that we can do this relatively easily. Putting together a basic schema like this to build upon is a great approach for prototyping—you have the data you need there, and can add complexity where you need, when you need it. Building models A single instance of a model maps directly to a single document in the database. With this 1:1 relationship, it is the model that handles all document interaction—creating, reading, saving, and deleting. This makes the model a very powerful tool. Building the model is pretty straightforward. When using the default Mongoose connection we can call the mongoose.model command, passing it two arguments: The name of the model The name of the schema to compile So if we were to build a model from our user schema we would use this line: mongoose.model( 'User', userSchema ); If you're using a named Mongoose connection, the approach is very similar. adminConnection.model( 'User', userSchema ); Instances It is useful to have a good understanding of how a model works. After building the User model, using the previous line we could create two instances. var userOne = new User({ name: 'Simon' });var userTwo = new User({ name: 'Sally' }); Summary In this article, we have looked at how schemas and models relate to your data. You should now understand the roles of both schemas and models. We have looked at how to create simple schemas and the types of data they can contain. We have also seen that it is possible to extend this if the native types are not enough. In the MongoosePM project, you should now have added a User schema and a Project schema, and built models of both of these. Resources for Article: Further resources on this subject: Understanding Express Routes [Article] Validating and Using the Model Data [Article] Creating Your First Web Page Using ExpressionEngine: Part 1 [Article]
Read more
  • 0
  • 0
  • 3735

article-image-nokogiri
Packt
27 Aug 2013
8 min read
Save for later

Nokogiri

Packt
27 Aug 2013
8 min read
(For more resources related to this topic, see here.) Spoofing browser agents When you request a web page, you send metainformation along with your request in the form of headers. One of these headers, User-agent, informs the web server which web browser you are using. By default open-uri, the library we are using to scrape, will report your browser as Ruby. There are two issues with this. First, it makes it very easy for an administrator to look through their server logs and see if someone has been scraping the server. Ruby is not a standard web browser. Second, some web servers will deny requests that are made by a nonstandard browsing agent. We are going to spoof our browser agent so that the server thinks we are just another Mac using Safari. An example is as follows: # import nokogiri to parse and open-uri to scraperequire 'nokogiri'require 'open-uri'# this string is the browser agent for Safari running on a Macbrowser = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4)AppleWebKit/536.30.1 (KHTML, like Gecko) Version/6.0.5Safari/536.30.1'# create a new Nokogiri HTML document from the scraped URL and pass inthe# browser agent as a second parameterdoc = Nokogiri::HTML(open('http://nytimes.com', browser))# you can now go along with your request as normal# you will show up as just another safari user in the logsputs doc.at_css('h2 a').to_s Caching It's important to remember that every time we scrape content, we are using someone else's server's resources. While it is true that we are not using any more resources than a standard web browser request, the automated nature of our requests leave the potential for abuse. In the previous examples we have searched for the top headline on The New York Times website. What if we took this code and put it in a loop because we always want to know the latest top headline? The code would work, but we would be launching a mini denial of service (DOS) attack on the server by hitting their page potentially thousands of times every minute. Many servers, Google being one example, have automatic blocking set up to prevent these rapid requests. They ban IP addresses that access their resources too quickly. This is known as rate limiting. To avoid being rate limited and in general be a good netizen, we need to implement a caching layer. Traditionally in a large app this would be implemented with a database. That's a little out of scope for this article, so we're going to build our own caching layer with a simple TXT file. We will store the headline in the file and then check the file modification date to see if enough time has passed before checking for new headlines. Start by creating the cache.txt file in the same directory as your code: $ touch cache.txt We're now ready to craft our caching solution: # import nokogiri to parse and open-uri to scraperequire 'nokogiri'require 'open-uri'# set how long in minutes until our data is expired# multiplied by 60 to convert to secondsexpiration = 1 * 60# file to store our cache incache = "cache.txt"# Calculate how old our cache is by subtracting it's modification time# from the current time.# Time.new gets the current time# The mtime methods gets the modification time on a filecache_age = Time.new - File.new(cache).mtime# if the cache age is greater than our expiration timeif cache_age > expiration# our cache has expireputs "cache has expired. fetching new headline"# we will now use our code from the quick start to# snag a new headline# scrape the web pagedata = open('http://nytimes.com')# create a Nokogiri HTML Document from our datadoc = Nokogiri::HTML(data)# parse the top headline and clean it upheadline = doc.at_css('h2 a').content.gsub(/n/," ").strip# we now need to save our new headline# the second File.open parameter "w" tells Ruby to overwrite# the old fileFile.open(cache, "w") do |file| # we then simply puts our text into the file file.puts headlineendputs "cache updated"else # we should use our cached copy puts "using cached copy" # read cache into a string using the read method headline = IO.read("cache.txt")end puts "The top headline on The New York Times is ..."puts headline Our cache is set to expire in one minute, so assuming it has been one minute since you created your cache.txt file, let's fire up our Ruby script: ruby cache.rbcache has expired. fetching new headlinecache updatedThe top headline on The New York Times is ...Supreme Court Invalidates Key Part of Voting Rights Act If we run our script again before another minute passes, it should use the cached copy: $ ruby cache.rbusing cached copyThe top headline on The New York Times is ...Supreme Court Invalidates Key Part of Voting Rights Act SSL By default, open-uri does not support scraping a page with SSL. This means any URL that starts with https will give you an error. We can get around this by adding one line below our require statements: # import nokogiri to parse and open-uri to scraperequire 'nokogiri'require 'open-uri'# disable SSL checking to allow scrapingOpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE Mechanize Sometimes you need to interact with a page before you can scrape it. The most common examples are logging in or submitting a form. Nokogiri is not set up to interact with pages. Nokogiri doesn't even scrape or download the page. That duty falls on open-uri. If you need to interact with a page, there is another gem you will have to use: Mechanize. Mechanize is created by the same team as Nokogiri and is used for automating interactions with websites. Mechanize includes a functioning copy of Nokogiri. To get started, install the mechanize gem: $ gem install mechanizeSuccessfully installed mechanize-2.7.1 We're going to recreate the code sample from the installation where we parsed the top Google results for "packt", except this time we are going to start by going to the Google home page and submitting the search form: # mechanize takes the place of Nokogiri and open-urirequire 'mechanize'# create a new mechanize agent# think of this as launching your web browseragent = Mechanize.new# open a URL in your agent / web browserpage = agent.get('http://google.com/')# the google homepage has one big search box# if you inspect the HTML, you will find a form with the name 'f'# inside of the form you will find a text input with the name 'q'google_form = page.form('f')# tell the page to set the q input inside the f form to 'packt'google_form.q = 'packt'# submit the formpage = agent.submit(google_form)# loop through an array of objects matching a CSS# selector. mechanize uses the search method instead of# xpath or css. search supports xpath and css# you can use the search method in Nokogiri too if you# like itpage.search('h3.r').each do |link| # print the link text puts link.contentend Now execute the Ruby script and you should see the titles for the top results: $ ruby mechanize.rbPackt Publishing: HomeBooksLatest BooksLogin/registerPacktLibSupportContactPackt - Wikipedia, the free encyclopediaPackt Open Source (PacktOpenSource) on TwitterPackt Publishing (packtpub) on TwitterPackt Publishing | LinkedInPackt Publishing | Facebook For more information refer to the site: http://mechanize.rubyforge.org/ People and places you should get to know If you need help with Nokogiri, here are some people and places that will prove invaluable. Official sites The following are the sites you can refer: Homepage and documentation: http://nokogiri.org Source code: https://github.com/sparklemotion/nokogiri/ Articles and tutorials The top five Nokogiri resources are as follows: Nokogiri History, Present, and Future presentation slides from Nokogiri co-author Mike Dalessio: http://bit.ly/nokogiri-goruco-2013 In-depth tutorial covering Ruby, Nokogiri, Sinatra, and Heroku complete with 90 minute behind-the-scenes screencast written by me: http://hunterpowers.com/data-scraping-and-more-with-ruby-nokogiri-sinatra-and-heroku RailsCasts episode 190: Screen Scraping with Nokogiri – an excellent Nokogiri quick start video: http://railscasts.com/episodes/190-screen-scraping-with-nokogiri Mechanize – an excellent Mechanize quick start video: http://railscasts.com/episodes/191-mechanize RailsCasts episode 191 Nokogiri co-author Mike Dalessio's blog: http://blog.flavorjon.es Community The community sites are as follows: Listserve: http://groups.google.com/group/nokogiri-talk GitHub: https://github.com/sparklemotion/nokogiri/ Wiki: http://github.com/sparklemotion/nokogiri/wikis Known issues: http://github.com/sparklemotion/nokogiri/issues Stackoverflow: http://stackoverflow.com/search?q=nokogiri Twitter Nokogiri leaders on Twitter are: Nokogiri co-author Mike Dalessio: @flavorjones Nokogiri co-author Aaron Patterson: @tenderlove Me: @TheHunter For more information on open source, follow Packt Publishing: @PacktOpenSource Summary Thus, we learnt about Nokogiri open source library in this article. Resources for Article : Further resources on this subject: URL Shorteners – Designing the TinyURL Clone with Ruby [Article] Introducing RubyMotion and the Hello World app [Article] Building the Facebook Clone using Ruby [Article]
Read more
  • 0
  • 0
  • 3002

article-image-creating-camel-project-simple
Packt
27 Aug 2013
8 min read
Save for later

Creating a Camel project (Simple)

Packt
27 Aug 2013
8 min read
(For more resources related to this topic, see here.) Getting ready For the examples in this article, we are going to use Apache Camel version 2.11 (http://maven.apache.org/) and Apache Maven version 2.2.1 or newer (http://maven.apache.org/) as a build tool. Both of these projects can be downloaded for free from their websites. The complete source code for all the examples in this article is available on github at https://github.com/bibryam/camel-message-routing-examples repository. It contains Camel routes in Spring XML and Java DSL with accompanying unit tests. The source code for this tutorial is located under the project: camel-message-routing-examples/creating-camel-project. How to do it... In a new Maven project add the following Camel dependency to the pom.xml: <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> <version>${camel-version}</version></dependency> With this dependency in place, creating our first route requires only a couple of lines of Java code: public class MoveFileRoute extends RouteBuilder { @Override public void configure() throws Exception { from("file://source") .to("log://org.apache.camel.howto?showAll=true") .to("file://target"); }} Once the route is defined, the next step is to add it to CamelContext, which is the actual routing engine and run it as a standalone Java application: public class Main { public static void main(String[] args) throws Exception { CamelContext camelContext = new DefaultCamelContext(); camelContext.addRoutes(new MoveFileRoute()); camelContext.start(); Thread.sleep(10000); camelContext.stop(); }} That's all it takes to create our first Camel application. Now, we can run it using a Java IDE or from the command line with Maven mvn exec:java. How it works... Camel has a modular architecture; its core (camel-core dependency) contains all the functionality needed to run a Camel application—DSL for various languages, the routing engine, implementations of EIPs, a number of data converters, and core components. This is the only dependency needed to run this application. Then there are optional technology specific connector dependencies (called components) such as JMS, SOAP, JDBC, Twitter, and so on, which are not needed for this example, as the file and log components we used are all part of the camel-core. Camel routes are created using a Domain Specific Language (DSL), specifically tailored for application integration. Camel DSLs are high-level languages that allow us to easily create routes, combining various processing steps and EIPs without going into low-level implementation details. In the Java DSL, we create a route by extending RouteBuilder and overriding the configure method. A route represents a chain of processing steps applied to a message based on some rules. The route has a beginning defined by the from endpoint, and one or more processing steps commonly called "Processors" (which implement the Processor interface). Most of these ideas and concepts originate from the Pipes and Filters pattern from the Enterprise Integration Patterns articlee by Gregor Hohpe and Bobby Woolf. The article provides an extensive list of patterns, which are also available at http://www.enterpriseintegrationpatterns.com, and the majority of which are implemented by Camel. With the Pipes and Filters pattern, a large processing task is divided into a sequence of smaller independent processing steps (Filters) that are connected by channels (Pipes). Each filter processes messages received from the inbound channel, and publishes the result to the outbound channel. In our route, the processing steps are reading the file using a polling consumer, logging it and writing the file to the target folder, all of them piped by Camel in the sequence specified in the DSL. We can visualize the individual steps in the application with the following diagram: A route has exactly one input called consumer and identified by the keyword from. A consumer receives messages from producers or external systems, wraps them in a Camel specific format called Exchange , and starts routing them. There are two types of consumers: a polling consumer that fetches messages periodically (for example, reading files from a folder) and an event-driven consumer that listens for events and gets activated when a message arrives (for example, an HTTP server). All the other processor nodes in the route are either a type of integration pattern or producers used for sending messages to various endpoints. Producers are identified by the keyword to and they are capable of converting exchanges and delivering them to other channels using the underlying transport mechanism. In our example, the log producer logs the files using the log4J API, whereas the file producer writes them to a target folder. The route is not enough to have a running application; it is only a template that defines the processing steps. The engine that runs and manages the routes is called Camel Context. A high level view of CamelContext looks like the following diagram: CamelContext is a dynamic multithread route container, responsible for managing all aspects of the routing: route lifecycle, message conversions, configurations, error handling, monitoring, and so on. When CamelContext is started, it starts the components, endpoints and activates the routes. The routes are kept running until CamelContext is stopped again when it performs a graceful shutdown giving time for all the in-flight messages to complete processing. CamelContext is dynamic, it allows us to start, stop routes, add new routes, or remove running routes at runtime. In our example, after adding the MoveFileRoute, we start CamelContext and let it copy files for 10 seconds, and then the application terminates. If we check the target folder, we should see files copied from the source folder. There's more... Camel applications can run as standalone applications or can be embedded in other containers such as Spring or Apache Karaf. To make development and deployment to various environments easy, Camel provides a number of DSLs, including Spring XML, Blueprint XML, Groovy, and Scala. Next, we will have a look at the Spring XML DSL. Using Spring XML DSL Java and Spring XML are the two most popular DSLs in Camel. Both provide access to all Camel features and the choice is mostly a matter of taste. Java DSL is more flexible and requires fewer lines of code, but can easily become complicated and harder to understand with the use of anonymous inner classes and other Java constructs. Spring XML DSL, on the other hand, is easier to read and maintain, but it is too verbose and testing it requires a little more effort. My rule of thumb is to use Spring XML DSL only when Camel is going to be part of a Spring application (to benefit from other Spring features available in Camel), or when the routing logic has to be easily understood by many people. For the routing examples in the article, we are going to show a mixture of Java and Spring XML DSL, but the source code accompanying this article has all the examples in both DSLs. In order to use Spring, we also need the following dependency in our projects: <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-spring</artifactId> <version>${camel-version}</version></dependency> The same application for copying files, written in Spring XML DSL looks like the following: <beans xsi_schemaLocation=" http ://www.springframework.org/schema/beans http ://www.springframework.org/schema/beans/spring-beans.xsd http ://camel.apache.org/schema/spring http ://camel.apache.org/schema/spring/camel-spring.xsd"><camelContext > <route> <from uri="file://source"/> <to uri="log://org.apache.camel.howto?showAll=true"/> <to uri="file://target"/> </route></camelContext></beans> Notice that this is a standard Spring XML file with an additional CamelContext element containing the route. We can launch the Spring application as part of a web application, OSGI bundle, or as a standalone application: public static void main(String[] args) throws Exception { AbstractApplicationContext springContext = new ClassPathXmlApplicationContext("META-INF/spring/move-file-context.xml"); springContext.start(); Thread.sleep(10000); springContext.stop();} When the Spring container starts, it will instantiate a CamelContext, start it and add the routes without any other code required. That is the complete application written in Spring XML DSL. More information about Spring support in Apache Camel can be found at http://camel.apache.org/spring.html. Summary This article provides a high-level overview of Camel architecture, and demonstrates how to create a simple message driven application. Resources for Article: Further resources on this subject: Binding Web Services in ESB—Web Services Gateway [Article] Drools Integration Modules: Spring Framework and Apache Camel [Article] Routing to an external ActiveMQ broker [Article]
Read more
  • 0
  • 0
  • 3956
article-image-exploitation-basics
Packt
27 Aug 2013
7 min read
Save for later

Exploitation Basics

Packt
27 Aug 2013
7 min read
(For more resources related to this topic, see here.) Basic terms of exploitation The basic terms of exploitation are explained as follows: Vulnerability: A vulnerability is a security hole in software or hardware, which allows an attacker to compromise a system. A vulnerability can be as simple as a weak password or as complex as a Denial of Service attack. Exploit: An exploit refers to a well-known security flaw or bug with which a hacker gains entry into a system. An exploit is the actual code with which an attacker takes advantage of a particular vulnerability. Payload: Once an exploit executes on the vulnerable system and the system has been compromised, the payload enables us to control the system. The payload is typically attached to the exploit and delivered. Shellcode: This is a set of instructions usually used as a payload when the exploitation occurs. Listener: A listener works as component waiting for an incoming connection. How does exploitation work? We consider the scenario of a computer lab in which we have two students doing work on their computers. After some time one of the students goes out for a coffee break and he responsibly locks down his computer. The password for that particular locked computer is Apple, which is a very simple dictionary word and is a system vulnerability. The other student starts to attempt a password guessing attack against the system of the student who left the lab. This is a classic example of an exploit. The controls that help the malicious user to control the system after successfully logging in to the computer are called the payload. We now come to the bigger question of how exploitation actually works. An attacker basically sends an exploit with an attached payload to the vulnerable system. The exploit runs first and if it succeeds, the actual code of the payload runs. After the payload runs, the attacker gets fully privileged access to the vulnerable system, and then he may download data, upload malware, virus', backdoors, or whatever he wants. A typical process for compromising a system For compromising any system, the first step is to scan the IP address to find open ports and its operating system and services. Then we move on to identifying a vulnerable service and finding an exploit in Metasploit for that particular service. If the exploit is not available in Metasploit, we will go through the Internet databases such as www.securityfocus.com, www.exploitdb.com, www.1337day.com, and so on. After successfully finding an exploit, we launch the exploit and compromise the system. The tools that are commonly used for port scanning are Nmap (Network Mapper), Autoscan, Unicorn Scan, and so on. For example, here we are using Nmap for scanning to show open ports and their services. First open the terminal in your BackTrack virtual machine. Type in nmap –v –n 192.168.0.103 and press Enter to scan. We use the –v parameter to get verbose output and the –n parameter to disable reverse DNS resolutions. Here we can see the results of Nmap, showing three open ports with their services running on them. If we need more detailed information such as the service version or Operating System type, we have to perform an intense scan using Nmap. For an intense scan, we use the command nmap –T4 –A –v 192.168.0.103. This shows us the complete results of the service version and the Operating System type. The next step is to find an exploit according to the service or its version. Here, we can see that the first service running on port number 135 is msrpc, which is known as Microsoft Windows RPC. Now we will learn how to find an exploit for this particular service in Metasploit. Let's open our terminal and type in msfconsole to start Metasploit. On typing in search dcom, it searches all of the Windows RPC related exploits in its database. In the following screenshot, we can see the exploit with its description and also the release date of this vulnerability. We are presented with a list of exploits according to their rank. From the three exploits related to this vulnerability, we select the first one since it is the most effective exploit with the highest rank. Now we have learned the technique of searching for an exploit in Metasploit through the search <service name> command. Finding exploits from online databases If the exploit is not available in Metasploit, then we have to search the Internet exploit databases for that particular exploit. Now we will learn how to search for an exploit on these online services such as www.1337day.com. We open the website and click on the Search tab. As an example, we will search for exploits on the Windows RPC service. Now we have to download and save a particular exploit. For this, just click on the exploit you need. After clicking on the exploit it shows the description of that exploit. Click on Open material to view or save the exploit. The usage of this exploit is provided as a part of the documentation in the exploit code as marked in the following screenshot: Now we will be exploiting our target machine with the particular exploit that we have downloaded. We have already scanned the IP address and found three open ports. The next step would be to exploit one of those ports. As an example, we will target the port number 135 service running on this target machine, which is msrpc. Let us start by compiling the downloaded exploit code. To compile the code, launch the terminal and type in gcc <exploit name with path> -o<exploitname>. For example, here we are typing gcc –dcom –o dcom. After compiling the exploit we have a binary file of that exploit, which we use to exploit the target by running the file in the terminal by typing in ./<filename>. From the preceding screenshot, we can see the requirements for exploiting the target. It requires the target IP address and the ID (Windows version). Let's have a look at our target IP address. We have the target IP address, so let's start the attack. Type in ./dcom 6 192.168.174.129. The target has been exploited and we already have the command shell. Now we check the IP address of the victim machine. Type in ipconfig. The target has been compromised and we have actually gained access to it. Now we will see how to use the internal exploits of Metasploit. We have already scanned an IP address and found three open ports. This time we target port number 445, which runs the Microsoft-ds service. Let us start by selecting an exploit. Launch msfconsole, type in use exploit/windows/smb/ms08_067_netapi, and press Enter. The next step will be to check the options for an exploit and what it requires in order to perform a successful exploitation. We type in show options and it will show us the requirements. We would need to set RHOST ( remote host), which is the target IP address, and let the other options keep their default values. We set up the RHOST or the target address by typing in set RHOST 192.168.0.103. After setting up the options, we are all set to exploit our target. Typing in exploit will give us the Meterpreter shell. References The following are some helpful references that shed further light on some of the topics covered in this article: http://www.securitytube.net/video/1175 http://resources.infosecinstitute.com/system-exploitation-metasploit/ Summary In this article, we covered the basics of vulnerability, a payload, and some tips on the art of exploitation. We also covered the techniques of how to search for vulnerable services and further query the Metasploit database for an exploit. These exploits were then used to compromise the vulnerable system. We also demonstrated the art of searching for exploits in Internet databases, which contain zero-day exploits on software and services. Resources for Article : Further resources on this subject: Understanding the True Security Posture of the Network Environment being Tested [Article] So, what is Metasploit? [Article] Tips and Tricks on BackTrack 4 [Article]
Read more
  • 0
  • 0
  • 6570

Packt
27 Aug 2013
6 min read
Save for later

WebSocket – a Handshake!

Packt
27 Aug 2013
6 min read
(For more resources related to this topic, see here.) WebSockets define a persistent two-way communication between web servers and web clients, meaning that both parties can exchange message data at the same time. WebSockets introduce true concurrency, they are optimized for high performance, and result in much more responsive and rich web applications. The following diagram shows a server handshake with multiple clients: For the record, the WebSocket protocol has been standardized by the Internet Engineering Task Force (IETF) and the WebSocket API for web browsers is currently being standardized by the World Wide Web Consortium (W3C)— yes, it's a work in progress. No, you do not need to worry about enormous changes, as the current specification has been published as "proposed standard". Life before WebSocket Before diving into the WebSockets' world, let's have a look at the existing techniques used for bidirectional communication between servers and clients. Polling Web engineers initially dealt with the issue using a technique called polling. Polling is a synchronous method (that is, no concurrency) that performs periodic requests, regardless whether data exists for transmission. The client makes consecutive requests after a specified time interval. Each time, the server responds with the available data or with a proper warning message. Though polling "just works", it is easy to understand that this method is overkill for most situations and extremely resource consuming for modern web apps. Long polling Long polling is a similar technique where, as its name indicates, the client opens a connection and the server keeps the connection active until some data is fetched or a timeout occurs. The client can then start over and perform a sequential request. Long polling is a performance improvement over polling, but the constant requests might slow down the process. Streaming Streaming seemed like the best option for real-time data transmission. When using streaming, the client performs a request and the server keeps the connection open indefinitely, fetching new data when ready. Although this is a big improvement, streaming still includes HTTP headers, which increase file size and cause unnecessary delays. Postback and AJAX The web has been built around the HTTP request-response model. HTTP is a stateless protocol, meaning that the communication between two parts consists of independent pairs of requests and responses. In plain words, the client asks the server for some information, the server responds with the proper HTML document and the page is refreshed (that's actually called a postback). Nothing happens in between, until a new action is performed (such as the click of a button or a selection from a drop-down menu). Any page load is followed by an annoying)(in terms of user experience) flickering effect. It was not until 2005 that the postback flickering was bypassed thanks to Asynchronous JavaScript and XML (AJAX). AJAX is based on the JavaScript's XmlHttpRequest Object and allows asynchronous execution of JavaScript code without interfering with the rest of the user interface. Instead of reloading the whole page, AJAX sends and receives back only a portion of the web page. Imagine you are using Facebook and want to post a comment on your Timeline. You type a status update in the proper text field, hit Enter and...voila! Your comment is automatically published without a single page load. Unless Facebook used AJAX, the browser would need to refresh the whole page in order to display your new status. AJAX, accompanied with popular JavaScript libraries such as jQuery, has strongly improved the end user experience and is widely considered as a must-have attribute for every website. It was only after AJAX that JavaScript became a respectable programming language, instead of being thought of as a necessary evil. But it's still not enough. Long polling is a useful technique that makes it seem like your browser maintains a persistent connection, while the truth is that the client makes continuous calls! This might be extremely resource-intensive, especially in mobile devices, where speed and data size really matter. All of the methods previously described provide real-time bidirectional communication, but have three obvious disadvantages in comparison with WebSockets: They send HTTP headers, making the total file size larger The communication type is half duplex, meaning that each party (client/server) must wait for the other one to finish The web server consumes more resources The postback world seems like a walkie-talkie—you need to wait for the other guy to finish speaking (half-duplex). In the WebSocket world, the participants can speak concurrently (full-duplex)! The web was initially built for displaying text documents, but think how it is used today. We display multimedia content, add location capabilities, accomplish complex tasks and, hence, transmit data different than text. AJAX and browser plugins such as Flash are all great, but a more native way of doing things is required. The way we use the web nowadays bears the need for a holistic new application development framework. Then came HTML5 HTML5 makes a huge, yet justifiable, buzz nowadays as it introduces vital solutions to the problems discussed previously. If you are already familiar with HTML5, feel free to skip this section and move on. HTML5 is a robust framework for developing and designing web applications. HTML5 is not just a new markup or some new styling selectors, neither is it a new programming language. HTML5 stands for a collection of technologies, programming languages and tools, each of which has a discrete role and all of these together accomplish a specific task—that is, to build rich web apps for any kind of device. The main HTML5 pillars include Markup, CSS3, and JavaScript APIs, together. The following diagram shows HTML5 components: Here are the dominant members of the HTML5 family. As this book does not cover the whole set of HTML5, I suggest you visit html5rocks.com and get started with hands-on examples and demos. Markup Structural elements Form elements Attributes Graphics Style sheets Canvas SVG WebGL Multimedia Audio Video Storage Cache Local storage Web SQL Connectivity WebMessaging WebSocket WebWorkers Location Geolocation Although Storage and Connectivity are supposed to be the most advanced topics, you do not need to worry if you are not an experienced web developer. Moreover, managing WebSockets via the HTML5 API is pretty simple to grasp, so take a deep breath and dive in with no fear. Summary This article has helped you understand the basics of WebSocket. It also helped you get an overview of life before WebSocket. It explained Postback and AJAX and then explained the topic of HTML5 Resources for Article: Further resources on this subject: Building HTML5 Pages from Scratch [Article] Basic use of Local Storage [Article] Scalability, Limitations, and Effects [Article]
Read more
  • 0
  • 0
  • 11314
Modal Close icon
Modal Close icon