├── CHANGELOG.md ├── Berksfile ├── Gemfile ├── test └── support │ └── Gemfile ├── .gitignore ├── Thorfile ├── .travis.yml ├── templates └── default │ ├── ops.txt.erb │ ├── banned-ips.txt.erb │ ├── banned-players.txt.erb │ ├── white-list.txt.erb │ ├── server.properties.erb │ └── minecraft.init.erb ├── metadata.rb ├── chefignore ├── LICENSE ├── Vagrantfile ├── attributes └── default.rb ├── recipes └── default.rb └── README.md /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ## v0.1 3 | * Initial release 4 | -------------------------------------------------------------------------------- /Berksfile: -------------------------------------------------------------------------------- 1 | site :opscode 2 | 3 | cookbook 'apt' 4 | 5 | metadata 6 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org" 2 | 3 | gem 'berkshelf' 4 | gem 'thor-foodcritic' 5 | -------------------------------------------------------------------------------- /test/support/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem 'thor' 4 | gem 'thor-foodcritic' 5 | gem 'foodcritic' 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant 2 | Berksfile.lock 3 | Gemfile.lock 4 | *~ 5 | *# 6 | .#* 7 | \#*# 8 | .*.sw[a-z] 9 | *.un~ 10 | /cookbooks 11 | -------------------------------------------------------------------------------- /Thorfile: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | require 'bundler' 4 | require 'bundler/setup' 5 | require 'thor/foodcritic' 6 | require 'berkshelf/thor' 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | gemfile: 3 | - test/support/Gemfile 4 | rvm: 5 | - 1.9.2 6 | - 1.9.3 7 | script: BUNDLE_GEMFILE=test/support/Gemfile bundle exec thor foodcritic:lint 8 | -------------------------------------------------------------------------------- /templates/default/ops.txt.erb: -------------------------------------------------------------------------------- 1 | <% if node['minecraft']['ops'].length > 0 -%> 2 | <% node['minecraft']['ops'].each do |device| -%> 3 | <%= node['minecraft']['ops'] %> 4 | <% end -%> 5 | <% end -%> 6 | 7 | -------------------------------------------------------------------------------- /templates/default/banned-ips.txt.erb: -------------------------------------------------------------------------------- 1 | <% if node['minecraft']['banned-ips'].length > 0 -%> 2 | <% node['minecraft']['banned-ips'].each do |device| -%> 3 | <%= node['minecraft']['banned-ips'] %> 4 | <% end -%> 5 | <% end -%> 6 | 7 | -------------------------------------------------------------------------------- /templates/default/banned-players.txt.erb: -------------------------------------------------------------------------------- 1 | <% if node['minecraft']['banned-players'].length > 0 -%> 2 | <% node['minecraft']['banned-players'].each do |device| -%> 3 | <%= node['minecraft']['banned-players'] %> 4 | <% end -%> 5 | <% end -%> 6 | 7 | -------------------------------------------------------------------------------- /templates/default/white-list.txt.erb: -------------------------------------------------------------------------------- 1 | <% if node['minecraft']['white-list-users'].length > 0 -%> 2 | <% node['minecraft']['white-list-users'].each do |device| -%> 3 | <%= node['minecraft']['white-list-users'] %> 4 | <% end -%> 5 | <% end -%> 6 | 7 | -------------------------------------------------------------------------------- /metadata.rb: -------------------------------------------------------------------------------- 1 | maintainer "Greg Fitzgerald" 2 | maintainer_email "greg@gregf.org" 3 | license "MIT" 4 | description "Installs/Configures minecraft server" 5 | long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) 6 | version "0.0.2" 7 | name "minecraft" 8 | 9 | recipe "minecraft", "Installs and configures minecraft server." 10 | 11 | %w{ java tmux }.each do |dep| 12 | depends dep 13 | end 14 | 15 | %w{ debian ubuntu }.each do |os| 16 | supports os 17 | end 18 | -------------------------------------------------------------------------------- /chefignore: -------------------------------------------------------------------------------- 1 | # Put files/directories that should be ignored in this file. 2 | # Lines that start with '# ' are comments. 3 | 4 | ## OS 5 | .DS_Store 6 | Icon? 7 | nohup.out 8 | 9 | ## EDITORS 10 | \#* 11 | .#* 12 | *~ 13 | *.sw[a-z] 14 | *.bak 15 | REVISION 16 | TAGS* 17 | tmtags 18 | *_flymake.* 19 | *_flymake 20 | *.tmproj 21 | .project 22 | .settings 23 | mkmf.log 24 | 25 | ## COMPILED 26 | a.out 27 | *.o 28 | *.pyc 29 | *.so 30 | 31 | ## OTHER SCM 32 | */.bzr/* 33 | */.hg/* 34 | */.svn/* 35 | 36 | ## Don't send rspecs up in cookbook 37 | .watchr 38 | .rspec 39 | spec/* 40 | spec/fixtures/* 41 | features/* 42 | 43 | ## SCM 44 | .gitignore 45 | 46 | # Berkshelf 47 | Berksfile 48 | Berksfile.lock 49 | cookbooks/* 50 | 51 | # Vagrant 52 | .vagrant 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2012, Greg Fitzgerald 2 | Permission is hereby granted, free of charge, to any person obtaining 3 | a copy of this software and associated documentation files (the 4 | "Software"), to deal in the Software without restriction, including 5 | without limitation the rights to use, copy, modify, merge, publish, 6 | distribute, sublicense, and/or sell copies of the Software, and to 7 | permit persons to whom the Software is furnished to do so, subject to 8 | the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be 11 | included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 15 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 16 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 17 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 18 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 19 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /templates/default/server.properties.erb: -------------------------------------------------------------------------------- 1 | #Minecraft server properties 2 | #<%= Time.now.strftime("%a %b %T %Z %Y") %> 3 | allow-nether=<%= node['minecraft']['allow-nether'] %> 4 | level-name=<%= node['minecraft']['level-name'] %> 5 | enable-query=<%= node['minecraft']['enable-query'] %> 6 | allow-flight=<%= node['minecraft']['allow-flight'] %> 7 | server-port=<%= node['minecraft']['server-port'] %> 8 | level-type=<%= node['minecraft']['level-type'] %> 9 | enable-rcon=<%= node['minecraft']['rcon'] %> 10 | level-seed=<%= node['minecraft']['level-seed'] %> 11 | server-ip=<%= node['minecraft']['server-ip'] %> 12 | max-build-height=<%= node['minecraft']['max-build-height'] %> 13 | spawn-npcs=<%= node['minecraft']['spawn-npcs'] %> 14 | white-list=<%= node['minecraft']['white-list'] %> 15 | spawn-animals=<%= node['minecraft']['spawn-animals'] %> 16 | online-mode=<%= node['minecraft']['online-mode'] %> 17 | pvp=<%= node['minecraft']['pvp'] %> 18 | difficulty=<%= node['minecraft']['difficulty'] %> 19 | gamemode=<%= node['minecraft']['gamemode'] %> 20 | max-players=<%= node['minecraft']['max-players'] %> 21 | spawn-monsters=<%= node['minecraft']['spawn-monsters'] %> 22 | generate-structures=<%= node['minecraft']['generate-structures'] %> 23 | view-distance=<%= node['minecraft']['view-distance'] %> 24 | motd=<%= node['minecraft']['motd'] %> 25 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | require 'berkshelf/vagrant' 2 | 3 | Vagrant::Config.run do |config| 4 | # All Vagrant configuration is done here. The most common configuration 5 | # options are documented and commented below. For a complete reference, 6 | # please see the online documentation at vagrantup.com. 7 | 8 | # The path to the Berksfile to use with Vagrant Berkshelf 9 | # config.berkshelf.berksfile_path = "./Berksfile" 10 | 11 | # The path to the Knife config to use with Vagrant Berkshelf 12 | # config.berkshelf.config_path = "~/.chef/knife.rb" 13 | 14 | # A client name (node_name) to use with the Chef Client provisioner to upload 15 | # cookbooks installed by Berkshelf. 16 | # config.berkshelf.node_name = "reset" 17 | 18 | # A path to a client key on disk to use with the Chef Client provisioner to 19 | # upload cookbooks installed by Berkshelf. 20 | # config.berkshelf.client_key = "~/.chef/reset.pem" 21 | 22 | # An array of symbols representing groups of cookbook described in the Vagrantfile 23 | # to skip installing and copying to Vagrant's shelf. 24 | # config.berkshelf.only = [] 25 | 26 | # An array of symbols representing groups of cookbook described in the Vagrantfile 27 | # to skip installing and copying to Vagrant's shelf. 28 | # config.berkshelf.except = [] 29 | 30 | config.vm.host_name = "minecraft-cookbook" 31 | 32 | config.vm.box = "opscode-ubuntu-12.04" 33 | config.vm.box_url = "https://opscode-vm.s3.amazonaws.com/vagrant/opscode_ubuntu-12.04_chef-10.18.2.box" 34 | 35 | config.vm.network :hostonly, "33.33.33.10" 36 | 37 | config.ssh.max_tries = 40 38 | config.ssh.timeout = 120 39 | 40 | config.vm.forward_port 25565, 25565 41 | 42 | config.vm.provision :chef_solo do |chef| 43 | chef.json = { 44 | :minecraft => { 45 | :xms => "256M", 46 | :xmx => "256M" 47 | } 48 | } 49 | chef.run_list = [ 50 | "recipe[apt]", 51 | "recipe[minecraft]" 52 | ] 53 | end 54 | 55 | end 56 | -------------------------------------------------------------------------------- /attributes/default.rb: -------------------------------------------------------------------------------- 1 | default['minecraft']['user'] = 'minecraft' 2 | default['minecraft']['install_dir'] = '/srv/minecraft' 3 | default['minecraft']['base_url'] = 'https://s3.amazonaws.com/MinecraftDownload/launcher' 4 | default['minecraft']['jar'] = 'minecraft_server.jar' 5 | default['minecraft']['checksum'] = '7a1abdac5d412b7eebefd84030d40c1591c17325801dba9cbbeb3fdf3c374553' 6 | 7 | default['minecraft']['xms'] = '1024M' 8 | default['minecraft']['xmx'] = '1024M' 9 | default['minecraft']['ipv6'] = false 10 | default['minecraft']['pid'] = '/var/run/minecraft.pid' 11 | 12 | default['minecraft']['banned-ips'] = [] 13 | default['minecraft']['banned-players'] = [] 14 | default['minecraft']['white-list-users'] = [] 15 | default['minecraft']['ops'] = [] 16 | 17 | default['minecraft']['allow-nether'] = true 18 | default['minecraft']['level-name'] = 'world' 19 | default['minecraft']['enable-query'] = false 20 | default['minecraft']['allow-flight'] = false 21 | default['minecraft']['server-port'] = 25565 22 | default['minecraft']['level-type'] = 'DEFAULT' 23 | default['minecraft']['enable_rcon'] = false 24 | default['minecraft']['level-seed'] = '' 25 | default['minecraft']['server-ip'] = '' 26 | default['minecraft']['max-build-height'] = 256 27 | default['minecraft']['spawn-npcs'] = true 28 | default['minecraft']['white-list'] = false 29 | default['minecraft']['spawn-animals'] = true 30 | default['minecraft']['online-mode'] = true 31 | default['minecraft']['pvp'] = true 32 | default['minecraft']['difficulty'] = 1 33 | default['minecraft']['gamemode'] = 0 34 | default['minecraft']['max-players'] = 20 35 | default['minecraft']['spawn-monsters'] = true 36 | default['minecraft']['generate-structures'] = true 37 | default['minecraft']['view-distance'] = 10 38 | default['minecraft']['motd'] = 'A Minecraft Server' 39 | -------------------------------------------------------------------------------- /templates/default/minecraft.init.erb: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ### BEGIN INIT INFO 3 | # Provides: Minecraft server 4 | # Required-Start: $local_fs $remote_fs 5 | # Required-Stop: $local_fs $remote_fs 6 | # Should-Start: $network 7 | # Should-Stop: $network 8 | # Default-Start: 2 3 4 5 9 | # Default-Stop: 0 1 6 10 | # Short-Description: Minecraft server 11 | # Description: Starts the minecraft server 12 | ### END INIT INFO 13 | 14 | # Author: Greg Fitzgerald 15 | 16 | # Settings 17 | PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 18 | USER="<%= node['minecraft']['user'] %>" 19 | SOCKET="/tmp/tmux-minecraft" 20 | MCJAR="<%= node['minecraft']['jar'] %>" 21 | XMS="<%= node['minecraft']['xms'] %>" 22 | XMX="<%= node['minecraft']['xmx'] %>" 23 | PIDFILE="<%= node['minecraft']['pid'] %>" 24 | HOME="<%= node['minecraft']['install_dir'] %>" 25 | NAME="Minecraft Server" 26 | SHUTDOWN_DELAY="30" 27 | 28 | [ -e $HOME/$MCJAR ] || exit 0 29 | 30 | set -e 31 | 32 | . /lib/lsb/init-functions 33 | 34 | isrunning() { 35 | ps ax | grep -Ev "tmux|sh|grep" | grep $MCJAR > /dev/null 36 | return $? 37 | } 38 | 39 | start() { 40 | if [ !isrunning ]; then 41 | start-stop-daemon \ 42 | --oknodo \ 43 | --start \ 44 | --make-pidfile \ 45 | --pidfile $PIDFILE \ 46 | --chdir $HOME \ 47 | --chuid $USER \ 48 | --exec /usr/bin/tmux -- -S $SOCKET new-session -n minecraft -d "java -server -Xincgc -Xms$XMS -Xmx$XMX -Djava.net.preferIPv4Stack=true -jar $MCJAR nogui" 49 | fi 50 | } 51 | 52 | stop() { 53 | if isrunning; then 54 | tmux -S $SOCKET -q send "say Server going down in $SHUTDOWN_DELAY seconds" C-m > /dev/null 55 | sleep $SHUTDOWN_DELAY 56 | tmux -S $SOCKET -q send "stop" C-m > /dev/null 57 | fi 58 | 59 | sleep 5 60 | 61 | if isrunning; then 62 | echo "$NAME failed to stop, trying to force a shutdown" 63 | minecraftPID=`ps ax | grep -Ev "grep|tmux|sh" $MCJAR` 64 | kill ${minecraftPID:0:5} 65 | fi 66 | 67 | sleep 2 68 | 69 | if isrunning; then 70 | echo "Was unable to kill $NAME" 71 | else 72 | echo "Sucessfully killed $NAME" 73 | fi 74 | } 75 | 76 | case "$1" in 77 | start) 78 | echo -n "Starting $NAME: " 79 | start 80 | echo "$NAME." 81 | ;; 82 | stop) 83 | echo -n "Stopping $NAME: " 84 | stop 85 | echo "$NAME." 86 | ;; 87 | restart) 88 | echo -n "Restarting $NAME: " 89 | stop 90 | echo "$NAME." 91 | start 92 | ;; 93 | status) 94 | if isrunning; then 95 | echo "$NAME is running" 96 | exit 0 97 | else 98 | echo "$NAME is not running" 99 | exit 1 100 | fi 101 | ;; 102 | *) 103 | echo "Usage: $NAME {start|stop|restart|status}" >&2 104 | exit 1 105 | ;; 106 | esac 107 | -------------------------------------------------------------------------------- /recipes/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook Name:: minecraft 3 | # Recipe:: default 4 | # 5 | # Copyright 2012, Greg Fitzgerald 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining 8 | # a copy of this software and associated documentation files (the 9 | # "Software"), to deal in the Software without restriction, including 10 | # without limitation the rights to use, copy, modify, merge, publish, 11 | # distribute, sublicense, and/or sell copies of the Software, and to 12 | # permit persons to whom the Software is furnished to do so, subject to 13 | # the following conditions: 14 | # 15 | # The above copyright notice and this permission notice shall be 16 | # included in all copies or substantial portions of the Software. 17 | # 18 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 22 | # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 24 | # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | # 26 | 27 | include_recipe 'java::default' 28 | include_recipe 'tmux::default' 29 | 30 | minecraft_jar = "#{Chef::Config['file_cache_path']}/#{node['minecraft']['jar']}" 31 | 32 | user node['minecraft']['user'] do 33 | system true 34 | comment "Minecraft Server" 35 | home node['minecraft']['install_dir'] 36 | shell "/bin/false" 37 | action :create 38 | end 39 | 40 | remote_file minecraft_jar do 41 | source "#{node['minecraft']['base_url']}/#{node['minecraft']['jar']}" 42 | checksum node['minecraft']['checksum'] 43 | owner node['minecraft']['user'] 44 | group node['minecraft']['user'] 45 | mode '0644' 46 | action :create_if_missing 47 | end 48 | 49 | directory node['minecraft']['install_dir'] do 50 | owner node['minecraft']['user'] 51 | group node['minecraft']['user'] 52 | mode '0755' 53 | action :create 54 | recursive true 55 | end 56 | 57 | execute "copy-minecraft_server.jar" do 58 | cwd node['minecraft']['install_dir'] 59 | command "cp -p #{minecraft_jar} ." 60 | creates "#{node['minecraft']['install_dir']}/minecraft_server.jar" 61 | end 62 | 63 | %w[ops.txt server.properties banned-ips.txt 64 | banned-players.txt white-list.txt].each do |template| 65 | template "#{node['minecraft']['install_dir']}/#{template}" do 66 | source "#{template}.erb" 67 | owner node['minecraft']['user'] 68 | group node['minecraft']['user'] 69 | mode 0644 70 | action :create 71 | end 72 | end 73 | 74 | template "/etc/init.d/minecraft" do 75 | source "minecraft.init.erb" 76 | owner "root" 77 | group "root" 78 | mode 00755 79 | end 80 | 81 | service "minecraft" do 82 | supports :restart => true 83 | action [ :enable, :start ] 84 | end 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Minecraft [![Build Status](https://secure.travis-ci.org/gregf/cookbook-minecraft.png)](http://travis-ci.org/gregf/cookbook-minecraft) 2 | 3 | ##Description 4 | 5 | Installs vanilla [Minecraft](http://www.minecraft.net) server. 6 | 7 | ##Requirements 8 | 9 | Requires the [java](http://community.opscode.com/cookbooks/java) and [tmux](http://community.opscode.com/cookbooks/tmux) cookbooks. 10 | 11 | ###Platform 12 | 13 | * Debian, Ubuntu 14 | 15 | ##Attributes 16 | 17 | See `attributes/default.rb` for default values. 18 | 19 | * `default['minecraft']['user']` 20 | * `default['minecraft']['install_dir']` 21 | * `default['minecraft']['base_url']` 22 | * `default['minecraft']['jar']` 23 | 24 | * `default['minecraft']['banned-ips']` 25 | * `default['minecraft']['banned-players']` 26 | * `default['minecraft']['white-list-users']` 27 | * `default['minecraft']['ops']` 28 | 29 | * `default['minecraft']['allow-nether']` 30 | * `default['minecraft']['level-name']` 31 | * `default['minecraft']['enable-query']` 32 | * `default['minecraft']['allow-flight']` 33 | * `default['minecraft']['server-port']` 34 | * `default['minecraft']['level-type']` 35 | * `default['minecraft']['enable_rcon']` 36 | * `default['minecraft']['level-seed']` 37 | * `default['minecraft']['server-ip']` 38 | * `default['minecraft']['max-build-height']` 39 | * `default['minecraft']['spawn-npcs']` 40 | * `default['minecraft']['white-list']` 41 | * `default['minecraft']['spawn-animals'] ` 42 | * `default['minecraft']['online-mode']` 43 | * `default['minecraft']['pvp']` 44 | * `default['minecraft']['difficulty']` 45 | * `default['minecraft']['gamemode']` 46 | * `default['minecraft']['max-players']` 47 | * `default['minecraft']['spawn-monsters']` 48 | * `default['minecraft']['generate-structures']` 49 | * `default['minecraft']['view-distance']` 50 | * `default['minecraft']['motd']` 51 | 52 | ##Usage 53 | 54 | Include the `minecraft` recipe and modify your run list and set any attributes 55 | you would like changed. 56 | 57 | run_list [ 58 | "recipe[minecraft]" 59 | ] 60 | "minecraft":{ 61 | "motd": "Welcome all griefers!" 62 | "max-players": 9001 63 | "ops": ["nappa", "goku"] 64 | } 65 | 66 | 67 | ##Recipes 68 | 69 | ###default 70 | 71 | Include the default recipe into your run_list to install `minecraft` server. 72 | Configuration files are prepopulated based on values in attributes. I will keep 73 | the defaults in sync with upstream. 74 | 75 | ##TODO 76 | 77 | * Clean up attributes 78 | * Test kitchen 79 | * Bukkit support or just wait for 1.5? 80 | 81 | ##License 82 | 83 | Copyright 2012, Greg Fitzgerald 84 | Permission is hereby granted, free of charge, to any person obtaining 85 | a copy of this software and associated documentation files (the 86 | "Software"), to deal in the Software without restriction, including 87 | without limitation the rights to use, copy, modify, merge, publish, 88 | distribute, sublicense, and/or sell copies of the Software, and to 89 | the following conditions: 90 | permit persons to whom the Software is furnished to do so, subject to 91 | 92 | The above copyright notice and this permission notice shall be 93 | included in all copies or substantial portions of the Software. 94 | 95 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 96 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 97 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 98 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 99 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 100 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 101 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 102 | 103 | --------------------------------------------------------------------------------